diff --git a/aptos-move/aptos-release-builder/src/components/feature_flags.rs b/aptos-move/aptos-release-builder/src/components/feature_flags.rs index 130ec720f1660..345bcbe6445e9 100644 --- a/aptos-move/aptos-release-builder/src/components/feature_flags.rs +++ b/aptos-move/aptos-release-builder/src/components/feature_flags.rs @@ -214,7 +214,7 @@ impl From for AptosFeatureFlag { match f { FeatureFlag::CodeDependencyCheck => AptosFeatureFlag::CODE_DEPENDENCY_CHECK, FeatureFlag::CollectAndDistributeGasFees => { - AptosFeatureFlag::COLLECT_AND_DISTRIBUTE_GAS_FEES + AptosFeatureFlag::_DEPRECATED_COLLECT_AND_DISTRIBUTE_GAS_FEES }, FeatureFlag::TreatFriendAsPrivate => AptosFeatureFlag::TREAT_FRIEND_AS_PRIVATE, FeatureFlag::Sha512AndRipeMd160Natives => { @@ -356,7 +356,7 @@ impl From for FeatureFlag { fn from(f: AptosFeatureFlag) -> Self { match f { AptosFeatureFlag::CODE_DEPENDENCY_CHECK => FeatureFlag::CodeDependencyCheck, - AptosFeatureFlag::COLLECT_AND_DISTRIBUTE_GAS_FEES => { + AptosFeatureFlag::_DEPRECATED_COLLECT_AND_DISTRIBUTE_GAS_FEES => { FeatureFlag::CollectAndDistributeGasFees }, AptosFeatureFlag::TREAT_FRIEND_AS_PRIVATE => FeatureFlag::TreatFriendAsPrivate, diff --git a/aptos-move/e2e-move-tests/src/lib.rs b/aptos-move/e2e-move-tests/src/lib.rs index b545f14251980..7d1f6343ceb2d 100644 --- a/aptos-move/e2e-move-tests/src/lib.rs +++ b/aptos-move/e2e-move-tests/src/lib.rs @@ -7,7 +7,6 @@ pub mod aptos_governance; pub mod harness; pub mod resource_groups; pub mod stake; -pub mod transaction_fee; use anyhow::bail; use aptos_framework::{BuildOptions, BuiltPackage, UPGRADE_POLICY_CUSTOM_FIELD}; diff --git a/aptos-move/e2e-move-tests/src/tests/mod.rs b/aptos-move/e2e-move-tests/src/tests/mod.rs index 33c8ac97e7ea0..f9ab23563390c 100644 --- a/aptos-move/e2e-move-tests/src/tests/mod.rs +++ b/aptos-move/e2e-move-tests/src/tests/mod.rs @@ -53,7 +53,6 @@ mod test_self; mod token_event_store; mod token_objects; mod transaction_context; -mod transaction_fee; mod type_too_large; mod vector_numeric_address; mod vm; diff --git a/aptos-move/e2e-move-tests/src/tests/transaction_fee.data/disable_collection/Move.toml b/aptos-move/e2e-move-tests/src/tests/transaction_fee.data/disable_collection/Move.toml deleted file mode 100644 index 0d3137c88dda4..0000000000000 --- a/aptos-move/e2e-move-tests/src/tests/transaction_fee.data/disable_collection/Move.toml +++ /dev/null @@ -1,6 +0,0 @@ -[package] -name = "DisableCollection" -version = "0.0.0" - -[dependencies] -AptosFramework = { local = "../../../../../framework/aptos-framework" } diff --git a/aptos-move/e2e-move-tests/src/tests/transaction_fee.data/disable_collection/sources/main.move b/aptos-move/e2e-move-tests/src/tests/transaction_fee.data/disable_collection/sources/main.move deleted file mode 100644 index 6162e01ab99ca..0000000000000 --- a/aptos-move/e2e-move-tests/src/tests/transaction_fee.data/disable_collection/sources/main.move +++ /dev/null @@ -1,16 +0,0 @@ -script { - use aptos_framework::aptos_governance; - use std::features; - - fun main(core_resources: &signer) { - let framework_signer = aptos_governance::get_signer_testnet_only(core_resources, @aptos_framework); - let feature = features::get_collect_and_distribute_gas_fees_feature(); - - // Trigger reconfiguration first, to also sync all the fees to validators. - aptos_governance::force_end_epoch(&framework_signer); - - // Then, disable the feature. - features::change_feature_flags_for_next_epoch(&framework_signer, vector[], vector[feature]); - aptos_governance::force_end_epoch(&framework_signer); - } -} diff --git a/aptos-move/e2e-move-tests/src/tests/transaction_fee.data/enable_collection/Move.toml b/aptos-move/e2e-move-tests/src/tests/transaction_fee.data/enable_collection/Move.toml deleted file mode 100644 index d6663892ecd6a..0000000000000 --- a/aptos-move/e2e-move-tests/src/tests/transaction_fee.data/enable_collection/Move.toml +++ /dev/null @@ -1,6 +0,0 @@ -[package] -name = "EnableCollection" -version = "0.0.0" - -[dependencies] -AptosFramework = { local = "../../../../../framework/aptos-framework" } diff --git a/aptos-move/e2e-move-tests/src/tests/transaction_fee.data/enable_collection/sources/main.move b/aptos-move/e2e-move-tests/src/tests/transaction_fee.data/enable_collection/sources/main.move deleted file mode 100644 index cfdc4b6be73cb..0000000000000 --- a/aptos-move/e2e-move-tests/src/tests/transaction_fee.data/enable_collection/sources/main.move +++ /dev/null @@ -1,13 +0,0 @@ -script { - use aptos_framework::aptos_governance; - use std::features; - - fun main(core_resources: &signer) { - let framework_signer = aptos_governance::get_signer_testnet_only(core_resources, @aptos_framework); - let feature = features::get_collect_and_distribute_gas_fees_feature(); - features::change_feature_flags_for_next_epoch(&framework_signer, vector[feature], vector[]); - - // Make sure to trigger a reconfiguration! - aptos_governance::force_end_epoch(&framework_signer); - } -} diff --git a/aptos-move/e2e-move-tests/src/tests/transaction_fee.data/initialize_collection/Move.toml b/aptos-move/e2e-move-tests/src/tests/transaction_fee.data/initialize_collection/Move.toml deleted file mode 100644 index d59053dbc9a7c..0000000000000 --- a/aptos-move/e2e-move-tests/src/tests/transaction_fee.data/initialize_collection/Move.toml +++ /dev/null @@ -1,6 +0,0 @@ -[package] -name = "InitializeCollection" -version = "0.0.0" - -[dependencies] -AptosFramework = { local = "../../../../../framework/aptos-framework" } diff --git a/aptos-move/e2e-move-tests/src/tests/transaction_fee.data/initialize_collection/sources/main.move b/aptos-move/e2e-move-tests/src/tests/transaction_fee.data/initialize_collection/sources/main.move deleted file mode 100644 index d2e0733a529e5..0000000000000 --- a/aptos-move/e2e-move-tests/src/tests/transaction_fee.data/initialize_collection/sources/main.move +++ /dev/null @@ -1,10 +0,0 @@ -script { - use aptos_framework::aptos_governance; - use aptos_framework::transaction_fee; - - fun main(core_resources: &signer, burn_percentage: u8) { - let framework_signer = aptos_governance::get_signer_testnet_only(core_resources, @aptos_framework); - transaction_fee::initialize_fee_collection_and_distribution(&framework_signer, burn_percentage); - // Since this only places resources on the core account, no reconfiguration is needed. - } -} diff --git a/aptos-move/e2e-move-tests/src/tests/transaction_fee.data/remove_validator/Move.toml b/aptos-move/e2e-move-tests/src/tests/transaction_fee.data/remove_validator/Move.toml deleted file mode 100644 index 172e15601db3d..0000000000000 --- a/aptos-move/e2e-move-tests/src/tests/transaction_fee.data/remove_validator/Move.toml +++ /dev/null @@ -1,6 +0,0 @@ -[package] -name = "RemoveCollection" -version = "0.0.0" - -[dependencies] -AptosFramework = { local = "../../../../../framework/aptos-framework" } diff --git a/aptos-move/e2e-move-tests/src/tests/transaction_fee.data/remove_validator/sources/main.move b/aptos-move/e2e-move-tests/src/tests/transaction_fee.data/remove_validator/sources/main.move deleted file mode 100644 index 37641f8b8e843..0000000000000 --- a/aptos-move/e2e-move-tests/src/tests/transaction_fee.data/remove_validator/sources/main.move +++ /dev/null @@ -1,12 +0,0 @@ -script { - use aptos_framework::aptos_governance; - use aptos_framework::stake; - - fun main(core_resources: &signer, addr: address) { - let framework_signer = aptos_governance::get_signer_testnet_only(core_resources, @aptos_framework); - stake::remove_validators(&framework_signer, &vector[addr]); - - // Make sure to trigger a reconfiguration! - aptos_governance::force_end_epoch(&framework_signer); - } -} diff --git a/aptos-move/e2e-move-tests/src/tests/transaction_fee.data/upgrade_burn_percentage/Move.toml b/aptos-move/e2e-move-tests/src/tests/transaction_fee.data/upgrade_burn_percentage/Move.toml deleted file mode 100644 index 1fb53040c0da1..0000000000000 --- a/aptos-move/e2e-move-tests/src/tests/transaction_fee.data/upgrade_burn_percentage/Move.toml +++ /dev/null @@ -1,6 +0,0 @@ -[package] -name = "UpgradeBurnPercentage" -version = "0.0.0" - -[dependencies] -AptosFramework = { local = "../../../../../framework/aptos-framework" } diff --git a/aptos-move/e2e-move-tests/src/tests/transaction_fee.data/upgrade_burn_percentage/sources/main.move b/aptos-move/e2e-move-tests/src/tests/transaction_fee.data/upgrade_burn_percentage/sources/main.move deleted file mode 100644 index 5a5fecd979ddd..0000000000000 --- a/aptos-move/e2e-move-tests/src/tests/transaction_fee.data/upgrade_burn_percentage/sources/main.move +++ /dev/null @@ -1,12 +0,0 @@ -script { - use aptos_framework::aptos_governance; - use aptos_framework::transaction_fee; - - fun main(core_resources: &signer, burn_percentage: u8) { - let framework_signer = aptos_governance::get_signer_testnet_only(core_resources, @aptos_framework); - transaction_fee::upgrade_burn_percentage(&framework_signer, burn_percentage); - - // Make sure to trigger a reconfiguration! - aptos_governance::force_end_epoch(&framework_signer); - } -} diff --git a/aptos-move/e2e-move-tests/src/tests/transaction_fee.rs b/aptos-move/e2e-move-tests/src/tests/transaction_fee.rs deleted file mode 100644 index 5f134c35ff841..0000000000000 --- a/aptos-move/e2e-move-tests/src/tests/transaction_fee.rs +++ /dev/null @@ -1,530 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -use crate::{ - assert_success, get_stake_pool, setup_staking, tests::common, transaction_fee, MoveHarness, -}; -use aptos_cached_packages::aptos_stdlib; -use aptos_language_e2e_tests::{account::Account, executor::FakeExecutor}; -use aptos_types::{ - account_address::AccountAddress, - on_chain_config::FeatureFlag, - transaction::{SignedTransaction, TransactionArgument, TransactionStatus}, -}; -use once_cell::sync::Lazy; -use rand::{ - distributions::Uniform, - rngs::{OsRng, StdRng}, - Rng, SeedableRng, -}; -use std::collections::BTreeMap; - -pub static PROPOSAL_SCRIPTS: Lazy>> = Lazy::new(build_scripts); - -fn build_scripts() -> BTreeMap> { - let package_folder = "transaction_fee.data"; - let package_names = vec![ - "initialize_collection", - "enable_collection", - "disable_collection", - "upgrade_burn_percentage", - "remove_validator", - ]; - common::build_scripts(package_folder, package_names) -} - -// Constants for calculating rewards for validators at the end of each epoch. -const INITIAL_STAKE_AMOUNT: u64 = 25_000_000; -const REWARDS_RATE_DENOMINATOR: u64 = 1_000_000_000; - -// Each epoch takes 1 hour in genesis config for tests. -const NUM_EPOCHS_IN_A_YEAR: u64 = 365 * 24; -const REWARDS_RATE: u64 = (10 * REWARDS_RATE_DENOMINATOR / 100) / NUM_EPOCHS_IN_A_YEAR; - -/// Holds all information about the current state of the chain, including -/// accounts of users, validators, etc. -struct TestUniverse { - harness: MoveHarness, - core_resources: Account, - validators: Vec, - users: Vec, -} - -// Make sure the number of users in this test universe is large enough. -const NUM_USERS: usize = 200; - -impl TestUniverse { - /// Creates a new testing universe with all necessary accounts created. - pub fn new(num_validators: usize) -> Self { - let executor = FakeExecutor::from_head_genesis().set_parallel(); - let mut harness = MoveHarness::new_with_executor(executor); - harness.set_default_gas_unit_price(1); - let core_resources = - harness.new_account_at(AccountAddress::from_hex_literal("0xA550C18").unwrap()); - let validators: Vec = (0..num_validators) - .map(|idx| { - harness.new_account_at( - AccountAddress::from_hex_literal(format!("0xa{}", idx).as_str()).unwrap(), - ) - }) - .collect(); - let users: Vec = (0..NUM_USERS) - .map(|idx| { - harness.new_account_at( - AccountAddress::from_hex_literal(format!("0xb{}", idx).as_str()).unwrap(), - ) - }) - .collect(); - Self { - harness, - core_resources, - validators, - users, - } - } - - /// Initializes validators with the given stake amount. - pub fn set_up_validators(&mut self, stake_amount: u64) { - self.validators.iter().for_each(|validator| { - assert_success!(setup_staking(&mut self.harness, validator, stake_amount)); - }); - self.harness.new_epoch(); - } - - /// Creates a block of p2p transactions in the universe. - pub fn create_block(&mut self, num_txns: usize) -> Vec { - let mut rng = StdRng::from_seed(OsRng.gen()); - let num_users = self.users.len(); - (0..num_txns) - .map(|_| { - // Select random users. - let src_account = &self.users[rng.sample(Uniform::new(0, num_users))]; - let dst_account = &self.users[rng.sample(Uniform::new(0, num_users))]; - - // Create a new p2p transaction. - self.harness.create_transaction_payload( - src_account, - aptos_stdlib::aptos_coin_transfer(*dst_account.address(), 1), - ) - }) - .collect() - } - - /// Injects a governance proposal script into transaction block. - pub fn inject_proposal_into_block( - &mut self, - block: &mut Vec, - proposal_idx: usize, - package_name: &str, - args: Vec, - ) { - let script_code = PROPOSAL_SCRIPTS - .get(package_name) - .expect("proposal script should be built"); - let sender = &self.core_resources; - let txn = self - .harness - .create_script(sender, script_code.clone(), vec![], args); - - debug_assert!(proposal_idx <= block.len()); - block.insert(proposal_idx, txn); - } - - /// Returns the total supply of AptosCoin in the universe. - pub fn read_total_supply(&mut self) -> u128 { - self.harness.executor.read_coin_supply().unwrap() - } -} - -/// For the given transaction outputs, calculates how much gas the block costs. -/// If there was a reconfiguration during the block execution, the cost is split -/// into before transaction triggering reconfiguration, and the cost of -/// transaction (governance proposal) triggering the reconfiguration. Note that -/// all outputs after reconfiguration should be Retry. -fn calculate_gas_used(outputs: Vec<(TransactionStatus, u64)>) -> (u64, u64) { - let mut found_reconfig = false; - let mut gas_used_for_reconfig = 0; - let mut total_gas_used = 0; - for (status, gas_used) in outputs { - total_gas_used += gas_used; - - if let TransactionStatus::Retry = status { - if !found_reconfig { - found_reconfig = true; - } - debug_assert!(gas_used == 0); - } else if !found_reconfig { - gas_used_for_reconfig = gas_used; - } - } - if !found_reconfig { - gas_used_for_reconfig = 0; - } - ( - total_gas_used - gas_used_for_reconfig, - gas_used_for_reconfig, - ) -} - -/// Tests a standard flow of collecting fees without any edge cases. -fn test_fee_collection_and_distribution_flow(burn_percentage: u8) { - let num_validators = 1; - let mut universe = TestUniverse::new(num_validators); - transaction_fee::initialize_fee_collection_and_distribution( - &mut universe.harness, - burn_percentage, - ); - universe - .harness - .enable_features(vec![FeatureFlag::COLLECT_AND_DISTRIBUTE_GAS_FEES], vec![]); - - let mut stake_amount = INITIAL_STAKE_AMOUNT; - universe.set_up_validators(stake_amount); - let rewards_per_epoch = stake_amount * REWARDS_RATE / REWARDS_RATE_DENOMINATOR; - assert_eq!(rewards_per_epoch, 285); - - // Run a single block and record how much gas it costs. Since fee collection - // is enabled, this amount is stored in aggregatable coin. - let validator_addr = *universe.validators[0].address(); - let txns = universe.create_block(1000); - - let mut total_supply = universe.read_total_supply(); - let outputs = universe - .harness - .run_block_with_metadata(validator_addr, vec![], txns); - let (p2p_gas, proposal_gas) = calculate_gas_used(outputs); - assert_eq!(proposal_gas, 0); - - let burnt_amount = (burn_percentage as u64) * p2p_gas / 100; - let collected_amount = p2p_gas - burnt_amount; - - // Drain aggregatable coin in the next block. - universe - .harness - .new_block_with_metadata(validator_addr, vec![]); - total_supply -= burnt_amount as u128; - - // Check that the right fraction was burnt. - assert_eq!(universe.read_total_supply(), total_supply); - - // On the new epoch, the collected fees are processed and added to the stake - // pool. - universe.harness.new_epoch(); - stake_amount += rewards_per_epoch + collected_amount; - assert_eq!( - get_stake_pool(&universe.harness, &validator_addr).active, - stake_amount - ); -} - -/// Tests if fees collection can be enabled by the governance proposal and how -/// fees are collected on the block boundary. -fn test_initialize_and_enable_fee_collection_and_distribution(burn_percentage: u8) { - let num_validators = 1; - let mut universe = TestUniverse::new(num_validators); - - let mut stake_amount = INITIAL_STAKE_AMOUNT; - universe.set_up_validators(stake_amount); - let rewards_per_epoch = stake_amount * REWARDS_RATE / REWARDS_RATE_DENOMINATOR; - assert_eq!(rewards_per_epoch, 285); - - // Create a block of transactions such that: - // 1. First 10 transactions are p2p. - // 2. A single transaction placing resources on chain. - // 3. Another 10 transactions are p2p. - // 4. A single transaction enabling fees collection. - // 5. Remaining transactions are p2p (should end up being Retry). - let mut txns = universe.create_block(50); - universe.inject_proposal_into_block(&mut txns, 10, "initialize_collection", vec![ - TransactionArgument::U8(burn_percentage), - ]); - universe.inject_proposal_into_block(&mut txns, 21, "enable_collection", vec![]); - - // Simulate block execution. - let mut total_supply = universe.read_total_supply(); - let validator_addr = *universe.validators[0].address(); - let outputs = universe - .harness - .run_block_with_metadata(validator_addr, vec![], txns); - let (gas_used, proposal_gas) = calculate_gas_used(outputs); - - // Reconfiguration triggers distributing rewards. - total_supply -= gas_used as u128; - total_supply += rewards_per_epoch as u128; - stake_amount += rewards_per_epoch; - assert_eq!(universe.read_total_supply(), total_supply); - assert_eq!( - get_stake_pool(&universe.harness, &validator_addr).active, - stake_amount - ); - - // In the previous block, the fee was only collected for the last script - // transaction which enabled the feature. In this block, we drain - // aggregatable coin and try to assign the fee to the validator. Since the - // proposer is not set (when feature flag was enabled), the fee is simply - // burnt and the stake pool should have the same value. - universe - .harness - .new_block_with_metadata(validator_addr, vec![]); - total_supply -= proposal_gas as u128; - assert_eq!(universe.read_total_supply(), total_supply); - assert_eq!( - get_stake_pool(&universe.harness, &validator_addr).active, - stake_amount - ); -} - -/// Tests fee collection can be safely disabled. The corner case here is that by disabling -/// the flag, we cannot distribute fees anymore unless it is done beforehand. -fn test_disable_fee_collection(burn_percentage: u8) { - let num_validators = 1; - let mut universe = TestUniverse::new(num_validators); - transaction_fee::initialize_fee_collection_and_distribution( - &mut universe.harness, - burn_percentage, - ); - universe - .harness - .enable_features(vec![FeatureFlag::COLLECT_AND_DISTRIBUTE_GAS_FEES], vec![]); - - let mut stake_amount = INITIAL_STAKE_AMOUNT; - universe.set_up_validators(stake_amount); - let rewards_per_epoch = stake_amount * REWARDS_RATE / REWARDS_RATE_DENOMINATOR; - assert_eq!(rewards_per_epoch, 285); - - // Create a block of transactions such that: - // 1. First 10 transactions are p2p. - // 2. A single transaction disabling fees collection. - // 3. Remaining transactions are p2p (should end up being Retry). - let mut txns = universe.create_block(100); - universe.inject_proposal_into_block(&mut txns, 10, "disable_collection", vec![]); - let validator_addr = *universe.validators[0].address(); - - // Simulate block execution. - let mut total_supply = universe.read_total_supply(); - let outputs = universe - .harness - .run_block_with_metadata(validator_addr, vec![], txns); - let (p2p_gas, proposal_gas) = calculate_gas_used(outputs); - - // Calculate the fees taht are supposed to be collected before the feature - // is disabled. - let burnt_amount = (burn_percentage as u64) * p2p_gas / 100; - let collected_amount = p2p_gas - burnt_amount; - - // Reconfiguration triggers distribution of both rewards and fees. - stake_amount += rewards_per_epoch + collected_amount; - total_supply += rewards_per_epoch as u128; - total_supply -= burnt_amount as u128; - assert_eq!( - get_stake_pool(&universe.harness, &validator_addr).active, - stake_amount - ); - - // Gas for the proposal should be burnt together with the fraction of the - // fees. - universe - .harness - .new_block_with_metadata(validator_addr, vec![]); - total_supply -= proposal_gas as u128; - assert_eq!(universe.read_total_supply(), total_supply); -} - -/// Tests that the fees collected prior to the upgrade use the right burn -/// percentage for calculations. -fn test_upgrade_burn_percentage(burn_percentage: u8) { - let num_validators = 2; - let mut universe = TestUniverse::new(num_validators); - transaction_fee::initialize_fee_collection_and_distribution( - &mut universe.harness, - burn_percentage, - ); - universe - .harness - .enable_features(vec![FeatureFlag::COLLECT_AND_DISTRIBUTE_GAS_FEES], vec![]); - - let mut stake_amount = INITIAL_STAKE_AMOUNT; - universe.set_up_validators(stake_amount); - - // Upgrade to the opposite value. - let new_burn_percentage = 100 - burn_percentage; - - // Create a block of transactions such that: - // 1. First 10 transactions are p2p. - // 2. A single transaction upgrading the burn percentage. - // 3. Remaining transactions are p2p (should end up being Retry). - let mut txns = universe.create_block(100); - universe.inject_proposal_into_block(&mut txns, 10, "upgrade_burn_percentage", vec![ - TransactionArgument::U8(new_burn_percentage), - ]); - let validator_addr = *universe.validators[0].address(); - - // Simulate block execution. - let mut total_supply = universe.read_total_supply(); - let outputs = universe - .harness - .run_block_with_metadata(validator_addr, vec![], txns); - let (p2p_gas, proposal_gas) = calculate_gas_used(outputs); - - let burnt_amount = (burn_percentage as u64) * p2p_gas / 100; - let collected_amount = p2p_gas - burnt_amount; - - // Compute rewards for this epoch. - let rewards_per_epoch = stake_amount * REWARDS_RATE / REWARDS_RATE_DENOMINATOR; - assert_eq!(rewards_per_epoch, 285); - - // Reconfiguration triggers distribution of rewards and fees. - stake_amount += rewards_per_epoch + collected_amount; - total_supply += rewards_per_epoch as u128; - total_supply -= burnt_amount as u128; - assert_eq!( - get_stake_pool(&universe.harness, &validator_addr).active, - stake_amount - ); - - // Gas for the proposal should be burnt together with fraction of fees. - universe - .harness - .new_block_with_metadata(validator_addr, vec![]); - total_supply -= proposal_gas as u128; - assert_eq!(universe.read_total_supply(), total_supply); - - // Now check that the new burn percentage works correctly. - let txns = universe.create_block(100); - total_supply = universe.read_total_supply(); - let outputs = universe - .harness - .run_block_with_metadata(validator_addr, vec![], txns); - let (gas_used, proposal_gas) = calculate_gas_used(outputs); - assert_eq!(proposal_gas, 0); - - let burnt_amount = (new_burn_percentage as u64) * gas_used / 100; - let collected_amount = gas_used - burnt_amount; - - // Check that the new fraction of fees is burnt. - universe - .harness - .new_block_with_metadata(validator_addr, vec![]); - total_supply -= burnt_amount as u128; - assert_eq!(universe.read_total_supply(), total_supply); - - // Check fees are distributed during the next epoch. Make sure to - // recalculate the rewards as well. - universe.harness.new_epoch(); - - // Compute rewards for this epoch. - let rewards_per_epoch = stake_amount * REWARDS_RATE / REWARDS_RATE_DENOMINATOR; - stake_amount += rewards_per_epoch + collected_amount; - assert_eq!( - get_stake_pool(&universe.harness, &validator_addr).active, - stake_amount - ); -} - -/// Tests that if validator running the block is removed, it still receives -/// previously collected fees. -fn test_leaving_validator_is_rewarded(burn_percentage: u8) { - let num_validators = 2; - let mut universe = TestUniverse::new(num_validators); - transaction_fee::initialize_fee_collection_and_distribution( - &mut universe.harness, - burn_percentage, - ); - universe - .harness - .enable_features(vec![FeatureFlag::COLLECT_AND_DISTRIBUTE_GAS_FEES], vec![]); - - let mut stake_amount = INITIAL_STAKE_AMOUNT; - universe.set_up_validators(stake_amount); - let rewards_per_epoch = stake_amount * REWARDS_RATE / REWARDS_RATE_DENOMINATOR; - assert_eq!(rewards_per_epoch, 285); - - // Create a block of transactions such that: - // 1. First 10 transactions are p2p. - // 2. A single transaction removing the validator. - // 3. Remaining transactions are p2p (should end up being Retry). - let removed_validator_addr = *universe.validators[0].address(); - let mut txns = universe.create_block(20); - universe.inject_proposal_into_block(&mut txns, 10, "remove_validator", vec![ - TransactionArgument::Address(removed_validator_addr), - ]); - - // Simulate block execution and calculate how much gas was used for - // transactions and for the governance proposal. - let mut total_supply = universe.read_total_supply(); - let outputs = universe - .harness - .run_block_with_metadata(removed_validator_addr, vec![], txns); - let (p2p_gas, proposal_gas) = calculate_gas_used(outputs); - - let burnt_amount = (burn_percentage as u64) * p2p_gas / 100; - let collected_amount = p2p_gas - burnt_amount; - - // Reconfiguration triggers distributing rewards and fees. - stake_amount += rewards_per_epoch + collected_amount; - total_supply += rewards_per_epoch as u128; - total_supply -= burnt_amount as u128; - assert_eq!( - get_stake_pool(&universe.harness, &removed_validator_addr).active, - stake_amount - ); - - let remaining_validator_addr = *universe.validators[1].address(); - universe - .harness - .new_block_with_metadata(remaining_validator_addr, vec![]); - total_supply -= proposal_gas as u128; - assert_eq!(universe.read_total_supply(), total_supply); -} - -#[test] -fn test_fee_collection_and_distribution_for_burn_percentages() { - // Test multiple burn percentages including the cases of 0 and 100. - for burn_percentage in [0, 50, 100] { - test_fee_collection_and_distribution_flow(burn_percentage); - test_initialize_and_enable_fee_collection_and_distribution(burn_percentage); - test_disable_fee_collection(burn_percentage); - test_upgrade_burn_percentage(burn_percentage); - test_leaving_validator_is_rewarded(burn_percentage); - } -} - -#[test] -/// Tests that fees for proposals are never leaked to the next block and are -/// always burnt. -fn test_block_single_proposal() { - let num_validators = 1; - let mut universe = TestUniverse::new(num_validators); - transaction_fee::initialize_fee_collection_and_distribution(&mut universe.harness, 100); - - let stake_amount = INITIAL_STAKE_AMOUNT; - universe.set_up_validators(stake_amount); - let rewards_per_epoch = stake_amount * REWARDS_RATE / REWARDS_RATE_DENOMINATOR; - assert_eq!(rewards_per_epoch, 285); - - // Create block with a single transaction: governance proposal to enable - // fee collection. This proposal ends the epoch. - let mut txns = vec![]; - universe.inject_proposal_into_block(&mut txns, 0, "enable_collection", vec![]); - let validator_addr = *universe.validators[0].address(); - - let mut total_supply = universe.read_total_supply(); - let outputs = universe - .harness - .run_block_with_metadata(validator_addr, vec![], txns); - let proposal_gas = outputs[1].1; - - // After reconfiguration rewards will be distributed. Because there are no - // other transactions, there is nothing to drain. However, this still should - // unset the proposer so that the next block burns the proposal fee. - total_supply += rewards_per_epoch as u128; - assert_eq!(universe.read_total_supply(), total_supply); - - // Ensure the fees are not leaked to the next block. This block must burn - // the proposal fee. - universe - .harness - .new_block_with_metadata(validator_addr, vec![]); - total_supply -= proposal_gas as u128; - assert_eq!(universe.read_total_supply(), total_supply); -} diff --git a/aptos-move/e2e-move-tests/src/transaction_fee.rs b/aptos-move/e2e-move-tests/src/transaction_fee.rs deleted file mode 100644 index 0f48b5d663823..0000000000000 --- a/aptos-move/e2e-move-tests/src/transaction_fee.rs +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -use crate::harness::MoveHarness; -use aptos_types::account_address::AccountAddress; -use move_core_types::value::MoveValue; - -pub fn initialize_fee_collection_and_distribution(harness: &mut MoveHarness, burn_percentage: u8) { - harness.executor.exec( - "transaction_fee", - "initialize_fee_collection_and_distribution", - vec![], - vec![ - MoveValue::Signer(AccountAddress::ONE) - .simple_serialize() - .unwrap(), - MoveValue::U8(burn_percentage).simple_serialize().unwrap(), - ], - ); -} - -pub fn upgrade_burn_percentage(harness: &mut MoveHarness, burn_percentage: u8) { - harness - .executor - .exec("transaction_fee", "upgrade_burn_percentage", vec![], vec![ - MoveValue::Signer(AccountAddress::ONE) - .simple_serialize() - .unwrap(), - MoveValue::U8(burn_percentage).simple_serialize().unwrap(), - ]); -} diff --git a/aptos-move/framework/aptos-framework/doc/aptos_governance.md b/aptos-move/framework/aptos-framework/doc/aptos_governance.md index 4daf73a12bded..bc58738f59e8a 100644 --- a/aptos-move/framework/aptos-framework/doc/aptos_governance.md +++ b/aptos-move/framework/aptos-framework/doc/aptos_governance.md @@ -2481,6 +2481,80 @@ The same as spec of + + +
schema CreateProposalAbortsIf {
+    proposer: &signer;
+    stake_pool: address;
+    execution_hash: vector<u8>;
+    metadata_location: vector<u8>;
+    metadata_hash: vector<u8>;
+    include VotingGetDelegatedVoterAbortsIf { sign: proposer };
+    include AbortsIfNotGovernanceConfig;
+    include GetVotingPowerAbortsIf { pool_address: stake_pool };
+    let staking_config = global<staking_config::StakingConfig>(@aptos_framework);
+    let allow_validator_set_change = staking_config.allow_validator_set_change;
+    let stake_pool_res = global<stake::StakePool>(stake_pool);
+    let stake_balance_0 = stake_pool_res.active.value + stake_pool_res.pending_active.value + stake_pool_res.pending_inactive.value;
+    let stake_balance_1 = stake_pool_res.active.value + stake_pool_res.pending_inactive.value;
+    let stake_balance_2 = 0;
+    let governance_config = global<GovernanceConfig>(@aptos_framework);
+    let required_proposer_stake = governance_config.required_proposer_stake;
+    // This enforces high-level requirement 2:
+    aborts_if allow_validator_set_change && stake_balance_0 < required_proposer_stake;
+    aborts_if !allow_validator_set_change && stake::spec_is_current_epoch_validator(stake_pool) && stake_balance_1 < required_proposer_stake;
+    aborts_if !allow_validator_set_change && !stake::spec_is_current_epoch_validator(stake_pool) && stake_balance_2 < required_proposer_stake;
+    aborts_if !exists<timestamp::CurrentTimeMicroseconds>(@aptos_framework);
+    let current_time = timestamp::spec_now_seconds();
+    let proposal_expiration = current_time + governance_config.voting_duration_secs;
+    aborts_if stake_pool_res.locked_until_secs < proposal_expiration;
+    include CreateProposalMetadataAbortsIf;
+    let addr = aptos_std::type_info::type_of<AptosCoin>().account_address;
+    aborts_if !exists<coin::CoinInfo<AptosCoin>>(addr);
+    let maybe_supply = global<coin::CoinInfo<AptosCoin>>(addr).supply;
+    let supply = option::spec_borrow(maybe_supply);
+    let total_supply = aptos_framework::optional_aggregator::optional_aggregator_value(supply);
+    let early_resolution_vote_threshold_value = total_supply / 2 + 1;
+    aborts_if option::spec_is_some(maybe_supply) && governance_config.min_voting_threshold > early_resolution_vote_threshold_value;
+    aborts_if len(execution_hash) == 0;
+    aborts_if !exists<voting::VotingForum<GovernanceProposal>>(@aptos_framework);
+    let voting_forum = global<voting::VotingForum<GovernanceProposal>>(@aptos_framework);
+    let proposal_id = voting_forum.next_proposal_id;
+    aborts_if proposal_id + 1 > MAX_U64;
+    let post post_voting_forum = global<voting::VotingForum<GovernanceProposal>>(@aptos_framework);
+    let post post_next_proposal_id = post_voting_forum.next_proposal_id;
+    ensures post_next_proposal_id == proposal_id + 1;
+    aborts_if !string::spec_internal_check_utf8(voting::IS_MULTI_STEP_PROPOSAL_KEY);
+    aborts_if !string::spec_internal_check_utf8(voting::IS_MULTI_STEP_PROPOSAL_IN_EXECUTION_KEY);
+    aborts_if table::spec_contains(voting_forum.proposals,proposal_id);
+    ensures table::spec_contains(post_voting_forum.proposals, proposal_id);
+    aborts_if !exists<GovernanceEvents>(@aptos_framework);
+}
+
+ + + + + + + +
schema VotingGetDelegatedVoterAbortsIf {
+    stake_pool: address;
+    sign: signer;
+    let addr = signer::address_of(sign);
+    let stake_pool_res = global<stake::StakePool>(stake_pool);
+    aborts_if !exists<stake::StakePool>(stake_pool);
+    aborts_if stake_pool_res.delegated_voter != addr;
+}
+
+ + @@ -2929,9 +3003,7 @@ Address @aptos_framework must exist ApprovedExecutionHashes and GovernancePropos framework: aptos_framework }; include stake::GetReconfigStartTimeRequirement; -include transaction_fee::RequiresCollectedFeesPerValueLeqBlockAptosSupply; requires chain_status::is_operating(); -requires exists<stake::ValidatorFees>(@aptos_framework); requires exists<CoinInfo<AptosCoin>>(@aptos_framework); requires exists<staking_config::StakingRewardsConfig>(@aptos_framework); include staking_config::StakingRewardsConfigRequirement; @@ -3006,9 +3078,7 @@ Address @aptos_framework must exist GovernanceConfig and GovernanceEvents. framework: aptos_framework }; include stake::GetReconfigStartTimeRequirement; -include transaction_fee::RequiresCollectedFeesPerValueLeqBlockAptosSupply; requires chain_status::is_operating(); -requires exists<stake::ValidatorFees>(@aptos_framework); requires exists<CoinInfo<AptosCoin>>(@aptos_framework); requires exists<staking_config::StakingRewardsConfig>(@aptos_framework); include staking_config::StakingRewardsConfigRequirement; diff --git a/aptos-move/framework/aptos-framework/doc/block.md b/aptos-move/framework/aptos-framework/doc/block.md index f5c4430007732..630da13126859 100644 --- a/aptos-move/framework/aptos-framework/doc/block.md +++ b/aptos-move/framework/aptos-framework/doc/block.md @@ -54,7 +54,6 @@ This module defines a struct storing the metadata of the block and new block eve use 0x1::system_addresses; use 0x1::table_with_length; use 0x1::timestamp; -use 0x1::transaction_fee;
@@ -616,15 +615,6 @@ Return epoch interval in seconds. }; emit_new_block_event(vm, &mut block_metadata_ref.new_block_events, new_block_event, new_block_event_v2); - if (features::collect_and_distribute_gas_fees()) { - // Assign the fees collected from the previous block to the previous block proposer. - // If for any reason the fees cannot be assigned, this function burns the collected coins. - transaction_fee::process_collected_fees(); - // Set the proposer of this block as the receiver of the fees, so that the fees for this - // block are assigned to the right account. - transaction_fee::register_proposer_for_fee_collection(proposer); - }; - // Performance scores have to be updated before the epoch transition as the transaction that triggers the // transition is the last block in the previous epoch. stake::update_performance_statistics(proposer_index, failed_proposer_indices); @@ -1088,6 +1078,68 @@ The number of new events created does not exceed MAX_U64. + + + + +
schema BlockRequirement {
+    vm: signer;
+    hash: address;
+    epoch: u64;
+    round: u64;
+    proposer: address;
+    failed_proposer_indices: vector<u64>;
+    previous_block_votes_bitvec: vector<u8>;
+    timestamp: u64;
+    requires chain_status::is_operating();
+    requires system_addresses::is_vm(vm);
+    // This enforces high-level requirement 4:
+    requires proposer == @vm_reserved || stake::spec_is_current_epoch_validator(proposer);
+    requires (proposer == @vm_reserved) ==> (timestamp::spec_now_microseconds() == timestamp);
+    requires (proposer != @vm_reserved) ==> (timestamp::spec_now_microseconds() < timestamp);
+    requires exists<CoinInfo<AptosCoin>>(@aptos_framework);
+    include staking_config::StakingRewardsConfigRequirement;
+}
+
+ + + + + + + +
schema Initialize {
+    aptos_framework: signer;
+    epoch_interval_microsecs: u64;
+    let addr = signer::address_of(aptos_framework);
+    // This enforces high-level requirement 2:
+    aborts_if addr != @aptos_framework;
+    aborts_if epoch_interval_microsecs == 0;
+    aborts_if exists<BlockResource>(addr);
+    aborts_if exists<CommitHistory>(addr);
+    ensures exists<BlockResource>(addr);
+    ensures exists<CommitHistory>(addr);
+    ensures global<BlockResource>(addr).height == 0;
+}
+
+ + + + + + + +
schema NewEventHandle {
+    aptos_framework: signer;
+    let addr = signer::address_of(aptos_framework);
+    let account = global<account::Account>(addr);
+    aborts_if !exists<account::Account>(addr);
+    aborts_if account.guid_creation_num + 2 > MAX_U64;
+}
+
+ + + ### Function `update_epoch_interval_microsecs` diff --git a/aptos-move/framework/aptos-framework/doc/coin.md b/aptos-move/framework/aptos-framework/doc/coin.md index f43569cd0787a..623f1dcb690b7 100644 --- a/aptos-move/framework/aptos-framework/doc/coin.md +++ b/aptos-move/framework/aptos-framework/doc/coin.md @@ -55,11 +55,6 @@ This module provides the foundation for typesafe Coins. - [Function `borrow_paired_burn_ref`](#0x1_coin_borrow_paired_burn_ref) - [Function `initialize_supply_config`](#0x1_coin_initialize_supply_config) - [Function `allow_supply_upgrades`](#0x1_coin_allow_supply_upgrades) -- [Function `initialize_aggregatable_coin`](#0x1_coin_initialize_aggregatable_coin) -- [Function `is_aggregatable_coin_zero`](#0x1_coin_is_aggregatable_coin_zero) -- [Function `drain_aggregatable_coin`](#0x1_coin_drain_aggregatable_coin) -- [Function `merge_aggregatable_coin`](#0x1_coin_merge_aggregatable_coin) -- [Function `collect_into_aggregatable_coin`](#0x1_coin_collect_into_aggregatable_coin) - [Function `calculate_amount_to_withdraw`](#0x1_coin_calculate_amount_to_withdraw) - [Function `maybe_convert_to_fungible_store`](#0x1_coin_maybe_convert_to_fungible_store) - [Function `migrate_to_fungible_store`](#0x1_coin_migrate_to_fungible_store) @@ -109,11 +104,6 @@ This module provides the foundation for typesafe Coins. - [Function `fungible_asset_to_coin`](#@Specification_1_fungible_asset_to_coin) - [Function `initialize_supply_config`](#@Specification_1_initialize_supply_config) - [Function `allow_supply_upgrades`](#@Specification_1_allow_supply_upgrades) - - [Function `initialize_aggregatable_coin`](#@Specification_1_initialize_aggregatable_coin) - - [Function `is_aggregatable_coin_zero`](#@Specification_1_is_aggregatable_coin_zero) - - [Function `drain_aggregatable_coin`](#@Specification_1_drain_aggregatable_coin) - - [Function `merge_aggregatable_coin`](#@Specification_1_merge_aggregatable_coin) - - [Function `collect_into_aggregatable_coin`](#@Specification_1_collect_into_aggregatable_coin) - [Function `maybe_convert_to_fungible_store`](#@Specification_1_maybe_convert_to_fungible_store) - [Function `coin_address`](#@Specification_1_coin_address) - [Function `balance`](#@Specification_1_balance) @@ -148,7 +138,6 @@ This module provides the foundation for typesafe Coins.
use 0x1::account;
 use 0x1::aggregator;
-use 0x1::aggregator_factory;
 use 0x1::create_signer;
 use 0x1::error;
 use 0x1::event;
@@ -201,12 +190,11 @@ Main structure representing a coin/token in an account's custody.
 
 ## Struct `AggregatableCoin`
 
-Represents a coin with aggregator as its value. This allows to update
-the coin in every transaction avoiding read-modify-write conflicts. Only
-used for gas fees distribution by Aptos Framework (0x1).
+DEPRECATED
 
 
-
struct AggregatableCoin<CoinType> has store
+
#[deprecated]
+struct AggregatableCoin<CoinType> has store
 
@@ -2025,189 +2013,6 @@ or disallow upgradability of total supply. - - - - -## Function `initialize_aggregatable_coin` - -Creates a new aggregatable coin with value overflowing on limit. Note that this function can -only be called by Aptos Framework (0x1) account for now because of create_aggregator. - - -
public(friend) fun initialize_aggregatable_coin<CoinType>(aptos_framework: &signer): coin::AggregatableCoin<CoinType>
-
- - - -
-Implementation - - -
public(friend) fun initialize_aggregatable_coin<CoinType>(aptos_framework: &signer): AggregatableCoin<CoinType> {
-    let aggregator = aggregator_factory::create_aggregator(aptos_framework, MAX_U64);
-    AggregatableCoin<CoinType> {
-        value: aggregator,
-    }
-}
-
- - - -
- - - -## Function `is_aggregatable_coin_zero` - -Returns true if the value of aggregatable coin is zero. - - -
public(friend) fun is_aggregatable_coin_zero<CoinType>(coin: &coin::AggregatableCoin<CoinType>): bool
-
- - - -
-Implementation - - -
public(friend) fun is_aggregatable_coin_zero<CoinType>(coin: &AggregatableCoin<CoinType>): bool {
-    let amount = aggregator::read(&coin.value);
-    amount == 0
-}
-
- - - -
- - - -## Function `drain_aggregatable_coin` - -Drains the aggregatable coin, setting it to zero and returning a standard coin. - - -
public(friend) fun drain_aggregatable_coin<CoinType>(coin: &mut coin::AggregatableCoin<CoinType>): coin::Coin<CoinType>
-
- - - -
-Implementation - - -
public(friend) fun drain_aggregatable_coin<CoinType>(coin: &mut AggregatableCoin<CoinType>): Coin<CoinType> {
-    spec {
-        // TODO: The data invariant is not properly assumed from CollectedFeesPerBlock.
-        assume aggregator::spec_get_limit(coin.value) == MAX_U64;
-    };
-    let amount = aggregator::read(&coin.value);
-    assert!(amount <= MAX_U64, error::out_of_range(EAGGREGATABLE_COIN_VALUE_TOO_LARGE));
-    spec {
-        update aggregate_supply<CoinType> = aggregate_supply<CoinType> - amount;
-    };
-    aggregator::sub(&mut coin.value, amount);
-    spec {
-        update supply<CoinType> = supply<CoinType> + amount;
-    };
-    Coin<CoinType> {
-        value: (amount as u64),
-    }
-}
-
- - - -
- - - -## Function `merge_aggregatable_coin` - -Merges coin into aggregatable coin (dst_coin). - - -
public(friend) fun merge_aggregatable_coin<CoinType>(dst_coin: &mut coin::AggregatableCoin<CoinType>, coin: coin::Coin<CoinType>)
-
- - - -
-Implementation - - -
public(friend) fun merge_aggregatable_coin<CoinType>(
-    dst_coin: &mut AggregatableCoin<CoinType>,
-    coin: Coin<CoinType>
-) {
-    spec {
-        update supply<CoinType> = supply<CoinType> - coin.value;
-    };
-    let Coin { value } = coin;
-    let amount = (value as u128);
-    spec {
-        update aggregate_supply<CoinType> = aggregate_supply<CoinType> + amount;
-    };
-    aggregator::add(&mut dst_coin.value, amount);
-}
-
- - - -
- - - -## Function `collect_into_aggregatable_coin` - -Collects a specified amount of coin form an account into aggregatable coin. - - -
public(friend) fun collect_into_aggregatable_coin<CoinType>(account_addr: address, amount: u64, dst_coin: &mut coin::AggregatableCoin<CoinType>)
-
- - - -
-Implementation - - -
public(friend) fun collect_into_aggregatable_coin<CoinType>(
-    account_addr: address,
-    amount: u64,
-    dst_coin: &mut AggregatableCoin<CoinType>,
-) acquires CoinStore, CoinConversionMap, CoinInfo, PairedCoinType {
-    // Skip collecting if amount is zero.
-    if (amount == 0) {
-        return
-    };
-
-    let (coin_amount_to_collect, fa_amount_to_collect) = calculate_amount_to_withdraw<CoinType>(
-        account_addr,
-        amount
-    );
-    let coin = if (coin_amount_to_collect > 0) {
-        let coin_store = borrow_global_mut<CoinStore<CoinType>>(account_addr);
-        extract(&mut coin_store.coin, coin_amount_to_collect)
-    } else {
-        zero()
-    };
-    if (fa_amount_to_collect > 0) {
-        let store_addr = primary_fungible_store::primary_store_address(
-            account_addr,
-            option::destroy_some(paired_metadata<CoinType>())
-        );
-        let fa = fungible_asset::withdraw_internal(store_addr, fa_amount_to_collect);
-        merge(&mut coin, fungible_asset_to_coin<CoinType>(fa));
-    };
-    merge_aggregatable_coin(dst_coin, coin);
-}
-
- - -
@@ -3814,70 +3619,13 @@ initialize, initialize_internal, initialize_with_parallelizable_supply; - - - - -
fun spec_is_account_registered<CoinType>(account_addr: address): bool {
-   let paired_metadata_opt = spec_paired_metadata<CoinType>();
-   exists<CoinStore<CoinType>>(account_addr) || (option::spec_is_some(
-       paired_metadata_opt
-   ) && primary_fungible_store::spec_primary_store_exists(account_addr, option::spec_borrow(paired_metadata_opt)))
-}
-
- - - - - - - -
schema CoinSubAbortsIf<CoinType> {
-    amount: u64;
-    let addr = type_info::type_of<CoinType>().account_address;
-    let maybe_supply = global<CoinInfo<CoinType>>(addr).supply;
-    include (option::is_some(
-        maybe_supply
-    )) ==> optional_aggregator::SubAbortsIf { optional_aggregator: option::borrow(maybe_supply), value: amount };
-}
-
- - - - - - - -
schema CoinAddAbortsIf<CoinType> {
-    amount: u64;
-    let addr = type_info::type_of<CoinType>().account_address;
-    let maybe_supply = global<CoinInfo<CoinType>>(addr).supply;
-    include (option::is_some(
-        maybe_supply
-    )) ==> optional_aggregator::AddAbortsIf { optional_aggregator: option::borrow(maybe_supply), value: amount };
-}
-
- - - - - - - -
schema AbortsIfNotExistCoinInfo<CoinType> {
-    let addr = type_info::type_of<CoinType>().account_address;
-    aborts_if !exists<CoinInfo<CoinType>>(addr);
-}
-
- - - ### Struct `AggregatableCoin` -
struct AggregatableCoin<CoinType> has store
+
#[deprecated]
+struct AggregatableCoin<CoinType> has store
 
@@ -3976,107 +3724,6 @@ Can only be updated by @aptos_framework. - - -### Function `initialize_aggregatable_coin` - - -
public(friend) fun initialize_aggregatable_coin<CoinType>(aptos_framework: &signer): coin::AggregatableCoin<CoinType>
-
- - - - -
include system_addresses::AbortsIfNotAptosFramework { account: aptos_framework };
-include aggregator_factory::CreateAggregatorInternalAbortsIf;
-
- - - - - -### Function `is_aggregatable_coin_zero` - - -
public(friend) fun is_aggregatable_coin_zero<CoinType>(coin: &coin::AggregatableCoin<CoinType>): bool
-
- - - - -
aborts_if false;
-ensures result == (aggregator::spec_read(coin.value) == 0);
-
- - - - - -### Function `drain_aggregatable_coin` - - -
public(friend) fun drain_aggregatable_coin<CoinType>(coin: &mut coin::AggregatableCoin<CoinType>): coin::Coin<CoinType>
-
- - - - -
aborts_if aggregator::spec_read(coin.value) > MAX_U64;
-ensures result.value == aggregator::spec_aggregator_get_val(old(coin).value);
-
- - - - - -### Function `merge_aggregatable_coin` - - -
public(friend) fun merge_aggregatable_coin<CoinType>(dst_coin: &mut coin::AggregatableCoin<CoinType>, coin: coin::Coin<CoinType>)
-
- - - - -
let aggr = dst_coin.value;
-let post p_aggr = dst_coin.value;
-aborts_if aggregator::spec_aggregator_get_val(aggr)
-    + coin.value > aggregator::spec_get_limit(aggr);
-aborts_if aggregator::spec_aggregator_get_val(aggr)
-    + coin.value > MAX_U128;
-ensures aggregator::spec_aggregator_get_val(aggr) + coin.value == aggregator::spec_aggregator_get_val(p_aggr);
-
- - - - - -### Function `collect_into_aggregatable_coin` - - -
public(friend) fun collect_into_aggregatable_coin<CoinType>(account_addr: address, amount: u64, dst_coin: &mut coin::AggregatableCoin<CoinType>)
-
- - - - -
pragma verify = false;
-let aggr = dst_coin.value;
-let post p_aggr = dst_coin.value;
-let coin_store = global<CoinStore<CoinType>>(account_addr);
-let post p_coin_store = global<CoinStore<CoinType>>(account_addr);
-aborts_if amount > 0 && !exists<CoinStore<CoinType>>(account_addr);
-aborts_if amount > 0 && coin_store.coin.value < amount;
-aborts_if amount > 0 && aggregator::spec_aggregator_get_val(aggr)
-    + amount > aggregator::spec_get_limit(aggr);
-aborts_if amount > 0 && aggregator::spec_aggregator_get_val(aggr)
-    + amount > MAX_U128;
-ensures aggregator::spec_aggregator_get_val(aggr) + amount == aggregator::spec_aggregator_get_val(p_aggr);
-ensures coin_store.coin.value - amount == p_coin_store.coin.value;
-
- - - ### Function `maybe_convert_to_fungible_store` @@ -4215,6 +3862,64 @@ Get address by reflection. + + + + +
fun spec_is_account_registered<CoinType>(account_addr: address): bool {
+   let paired_metadata_opt = spec_paired_metadata<CoinType>();
+   exists<CoinStore<CoinType>>(account_addr) || (option::spec_is_some(
+       paired_metadata_opt
+   ) && primary_fungible_store::spec_primary_store_exists(account_addr, option::spec_borrow(paired_metadata_opt)))
+}
+
+ + + + + + + +
schema CoinSubAbortsIf<CoinType> {
+    amount: u64;
+    let addr = type_info::type_of<CoinType>().account_address;
+    let maybe_supply = global<CoinInfo<CoinType>>(addr).supply;
+    include (option::is_some(
+        maybe_supply
+    )) ==> optional_aggregator::SubAbortsIf { optional_aggregator: option::borrow(maybe_supply), value: amount };
+}
+
+ + + + + + + +
schema CoinAddAbortsIf<CoinType> {
+    amount: u64;
+    let addr = type_info::type_of<CoinType>().account_address;
+    let maybe_supply = global<CoinInfo<CoinType>>(addr).supply;
+    include (option::is_some(
+        maybe_supply
+    )) ==> optional_aggregator::AddAbortsIf { optional_aggregator: option::borrow(maybe_supply), value: amount };
+}
+
+ + + + + + + +
schema AbortsIfNotExistCoinInfo<CoinType> {
+    let addr = type_info::type_of<CoinType>().account_address;
+    aborts_if !exists<CoinInfo<CoinType>>(addr);
+}
+
+ + + ### Function `name` diff --git a/aptos-move/framework/aptos-framework/doc/consensus_config.md b/aptos-move/framework/aptos-framework/doc/consensus_config.md index ddceb292dbded..d0ec4636cbfe3 100644 --- a/aptos-move/framework/aptos-framework/doc/consensus_config.md +++ b/aptos-move/framework/aptos-framework/doc/consensus_config.md @@ -348,7 +348,6 @@ When setting now time must be later than last_reconfiguration_time.
pragma verify_duration_estimate = 600;
-include transaction_fee::RequiresCollectedFeesPerValueLeqBlockAptosSupply;
 include staking_config::StakingRewardsConfigRequirement;
 let addr = signer::address_of(account);
 // This enforces high-level requirement 2:
@@ -358,7 +357,6 @@ When setting now time must be later than last_reconfiguration_time.
 aborts_if !(len(config) > 0);
 requires chain_status::is_genesis();
 requires timestamp::spec_now_microseconds() >= reconfiguration::last_reconfiguration_time();
-requires exists<stake::ValidatorFees>(@aptos_framework);
 requires exists<CoinInfo<AptosCoin>>(@aptos_framework);
 ensures global<ConsensusConfig>(@aptos_framework).config == config;
 
diff --git a/aptos-move/framework/aptos-framework/doc/execution_config.md b/aptos-move/framework/aptos-framework/doc/execution_config.md index 06be205963675..51d27a48e5bda 100644 --- a/aptos-move/framework/aptos-framework/doc/execution_config.md +++ b/aptos-move/framework/aptos-framework/doc/execution_config.md @@ -202,9 +202,7 @@ When setting now time must be later than last_reconfiguration_time.
pragma verify_duration_estimate = 600;
 let addr = signer::address_of(account);
-include transaction_fee::RequiresCollectedFeesPerValueLeqBlockAptosSupply;
 requires chain_status::is_genesis();
-requires exists<stake::ValidatorFees>(@aptos_framework);
 requires exists<staking_config::StakingRewardsConfig>(@aptos_framework);
 requires len(config) > 0;
 include features::spec_periodical_reward_rate_decrease_enabled() ==> staking_config::StakingRewardsConfigEnabledRequirement;
diff --git a/aptos-move/framework/aptos-framework/doc/gas_schedule.md b/aptos-move/framework/aptos-framework/doc/gas_schedule.md
index ea4a92886698f..ef5a2cec772ea 100644
--- a/aptos-move/framework/aptos-framework/doc/gas_schedule.md
+++ b/aptos-move/framework/aptos-framework/doc/gas_schedule.md
@@ -525,10 +525,8 @@ Only used in reconfigurations to apply the pending stake::ValidatorFees>(@aptos_framework);
 requires exists<CoinInfo<AptosCoin>>(@aptos_framework);
 requires chain_status::is_genesis();
-include transaction_fee::RequiresCollectedFeesPerValueLeqBlockAptosSupply;
 include staking_config::StakingRewardsConfigRequirement;
 // This enforces high-level requirement 2:
 include system_addresses::AbortsIfNotAptosFramework{ account: aptos_framework };
@@ -621,10 +619,8 @@ Only used in reconfigurations to apply the pending stake::ValidatorFees>(@aptos_framework);
 requires exists<CoinInfo<AptosCoin>>(@aptos_framework);
 include system_addresses::AbortsIfNotAptosFramework{ account: aptos_framework };
-include transaction_fee::RequiresCollectedFeesPerValueLeqBlockAptosSupply;
 include staking_config::StakingRewardsConfigRequirement;
 aborts_if !exists<StorageGasConfig>(@aptos_framework);
 ensures global<StorageGasConfig>(@aptos_framework) == config;
diff --git a/aptos-move/framework/aptos-framework/doc/genesis.md b/aptos-move/framework/aptos-framework/doc/genesis.md
index 5fcac753d7489..e767985fbd881 100644
--- a/aptos-move/framework/aptos-framework/doc/genesis.md
+++ b/aptos-move/framework/aptos-framework/doc/genesis.md
@@ -1139,10 +1139,8 @@ The last step of genesis.
     requires chain_status::is_operating();
     requires len(execution_config) > 0;
     requires exists<staking_config::StakingRewardsConfig>(@aptos_framework);
-    requires exists<stake::ValidatorFees>(@aptos_framework);
     requires exists<coin::CoinInfo<AptosCoin>>(@aptos_framework);
     include CompareTimeRequires;
-    include transaction_fee::RequiresCollectedFeesPerValueLeqBlockAptosSupply;
 }
 
diff --git a/aptos-move/framework/aptos-framework/doc/reconfiguration.md b/aptos-move/framework/aptos-framework/doc/reconfiguration.md index 3415e0a820de1..216bf3e672a58 100644 --- a/aptos-move/framework/aptos-framework/doc/reconfiguration.md +++ b/aptos-move/framework/aptos-framework/doc/reconfiguration.md @@ -44,7 +44,6 @@ to synchronize configuration changes for the validators. use 0x1::storage_gas; use 0x1::system_addresses; use 0x1::timestamp; -use 0x1::transaction_fee;
@@ -396,20 +395,6 @@ Signal validators to start using new configuration. Must be called from friend c reconfiguration_state::on_reconfig_start(); - // Reconfiguration "forces the block" to end, as mentioned above. Therefore, we must process the collected fees - // explicitly so that staking can distribute them. - // - // This also handles the case when a validator is removed due to the governance proposal. In particular, removing - // the validator causes a reconfiguration. We explicitly process fees, i.e. we drain aggregatable coin and populate - // the fees table, prior to calling `on_new_epoch()`. That call, in turn, distributes transaction fees for all active - // and pending_inactive validators, which include any validator that is to be removed. - if (features::collect_and_distribute_gas_fees()) { - // All transactions after reconfiguration are Retry. Therefore, when the next - // block starts and tries to assign/burn collected fees it will be just 0 and - // nothing will be assigned. - transaction_fee::process_collected_fees(); - }; - // Call stake to compute the new validator set and distribute rewards and transaction fees. stake::on_new_epoch(); storage_gas::on_reconfig(); @@ -726,12 +711,10 @@ Make sure the caller is admin and check the resource DisableReconfiguration.
pragma verify = true;
 pragma verify_duration_estimate = 600;
-requires exists<stake::ValidatorFees>(@aptos_framework);
 let success = !(chain_status::is_genesis() || timestamp::spec_now_microseconds() == 0 || !reconfiguration_enabled())
     && timestamp::spec_now_microseconds() != global<Configuration>(@aptos_framework).last_reconfiguration_time;
 include features::spec_periodical_reward_rate_decrease_enabled() ==> staking_config::StakingRewardsConfigEnabledRequirement;
 include success ==> aptos_coin::ExistsAptosCoin;
-include transaction_fee::RequiresCollectedFeesPerValueLeqBlockAptosSupply;
 aborts_if false;
 ensures success ==> global<Configuration>(@aptos_framework).epoch == old(global<Configuration>(@aptos_framework).epoch) + 1;
 ensures success ==> global<Configuration>(@aptos_framework).last_reconfiguration_time == timestamp::spec_now_microseconds();
diff --git a/aptos-move/framework/aptos-framework/doc/reconfiguration_with_dkg.md b/aptos-move/framework/aptos-framework/doc/reconfiguration_with_dkg.md
index 005fd6f824902..ba6bd01bb02a0 100644
--- a/aptos-move/framework/aptos-framework/doc/reconfiguration_with_dkg.md
+++ b/aptos-move/framework/aptos-framework/doc/reconfiguration_with_dkg.md
@@ -208,8 +208,6 @@ Abort if no DKG is in progress.
     requires chain_status::is_operating();
     requires exists<CoinInfo<AptosCoin>>(@aptos_framework);
     include staking_config::StakingRewardsConfigRequirement;
-    requires exists<stake::ValidatorFees>(@aptos_framework);
-    include transaction_fee::RequiresCollectedFeesPerValueLeqBlockAptosSupply;
     requires exists<features::Features>(@std);
     include config_buffer::OnNewEpochRequirement<version::Version>;
     include config_buffer::OnNewEpochRequirement<gas_schedule::GasScheduleV2>;
diff --git a/aptos-move/framework/aptos-framework/doc/stake.md b/aptos-move/framework/aptos-framework/doc/stake.md
index 017d83723ad91..b209d06483577 100644
--- a/aptos-move/framework/aptos-framework/doc/stake.md
+++ b/aptos-move/framework/aptos-framework/doc/stake.md
@@ -63,8 +63,6 @@ or if their stake drops below the min required, they would get removed at the en
 -  [Resource `Ghost$ghost_active_num`](#0x1_stake_Ghost$ghost_active_num)
 -  [Resource `Ghost$ghost_pending_inactive_num`](#0x1_stake_Ghost$ghost_pending_inactive_num)
 -  [Constants](#@Constants_0)
--  [Function `initialize_validator_fees`](#0x1_stake_initialize_validator_fees)
--  [Function `add_transaction_fee`](#0x1_stake_add_transaction_fee)
 -  [Function `get_lockup_secs`](#0x1_stake_get_lockup_secs)
 -  [Function `get_remaining_lockup_secs`](#0x1_stake_get_remaining_lockup_secs)
 -  [Function `get_stake`](#0x1_stake_get_stake)
@@ -130,8 +128,6 @@ or if their stake drops below the min required, they would get removed at the en
     -  [High-level Requirements](#high-level-req)
     -  [Module-level Specification](#module-level-spec)
     -  [Resource `ValidatorSet`](#@Specification_1_ValidatorSet)
-    -  [Function `initialize_validator_fees`](#@Specification_1_initialize_validator_fees)
-    -  [Function `add_transaction_fee`](#@Specification_1_add_transaction_fee)
     -  [Function `get_validator_state`](#@Specification_1_get_validator_state)
     -  [Function `initialize`](#@Specification_1_initialize)
     -  [Function `remove_validators`](#@Specification_1_remove_validators)
@@ -1447,11 +1443,11 @@ This allows the Stake module to mint rewards to stakers.
 
 ## Resource `ValidatorFees`
 
-Stores transaction fees assigned to validators. All fees are distributed to validators
-at the end of the epoch.
+DEPRECATED
 
 
-
struct ValidatorFees has key
+
#[deprecated]
+struct ValidatorFees has key
 
@@ -1882,68 +1878,6 @@ Validator status enum. We can switch to proper enum later once Move supports it. - - -## Function `initialize_validator_fees` - -Initializes the resource storing information about collected transaction fees per validator. -Used by transaction_fee.move to initialize fee collection and distribution. - - -
public(friend) fun initialize_validator_fees(aptos_framework: &signer)
-
- - - -
-Implementation - - -
public(friend) fun initialize_validator_fees(aptos_framework: &signer) {
-    system_addresses::assert_aptos_framework(aptos_framework);
-    assert!(
-        !exists<ValidatorFees>(@aptos_framework),
-        error::already_exists(EFEES_TABLE_ALREADY_EXISTS)
-    );
-    move_to(aptos_framework, ValidatorFees { fees_table: table::new() });
-}
-
- - - -
- - - -## Function `add_transaction_fee` - -Stores the transaction fee collected to the specified validator address. - - -
public(friend) fun add_transaction_fee(validator_addr: address, fee: coin::Coin<aptos_coin::AptosCoin>)
-
- - - -
-Implementation - - -
public(friend) fun add_transaction_fee(validator_addr: address, fee: Coin<AptosCoin>) acquires ValidatorFees {
-    let fees_table = &mut borrow_global_mut<ValidatorFees>(@aptos_framework).fees_table;
-    if (table::contains(fees_table, validator_addr)) {
-        let collected_fee = table::borrow_mut(fees_table, validator_addr);
-        coin::merge(collected_fee, fee);
-    } else {
-        table::add(fees_table, validator_addr, fee);
-    }
-}
-
- - - -
- ## Function `get_lockup_secs` @@ -3665,7 +3599,7 @@ power.
public(friend) fun on_new_epoch(
-) acquires StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+) acquires StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet {
     let validator_set = borrow_global_mut<ValidatorSet>(@aptos_framework);
     let config = staking_config::get();
     let validator_perf = borrow_global_mut<ValidatorPerformance>(@aptos_framework);
@@ -3826,7 +3760,7 @@ Return the ValidatorConsensusInfo of each current validator, sorted
 Implementation
 
 
-
public fun next_validator_consensus_infos(): vector<ValidatorConsensusInfo> acquires ValidatorSet, ValidatorPerformance, StakePool, ValidatorFees, ValidatorConfig {
+
public fun next_validator_consensus_infos(): vector<ValidatorConsensusInfo> acquires ValidatorSet, ValidatorPerformance, StakePool, ValidatorConfig {
     // Init.
     let cur_validator_set = borrow_global<ValidatorSet>(@aptos_framework);
     let staking_config = staking_config::get();
@@ -3881,25 +3815,16 @@ Return the ValidatorConsensusInfo of each current validator, sorted
             0
         };
 
-        let cur_fee = 0;
-        if (features::collect_and_distribute_gas_fees()) {
-            let fees_table = &borrow_global<ValidatorFees>(@aptos_framework).fees_table;
-            if (table::contains(fees_table, candidate.addr)) {
-                let fee_coin = table::borrow(fees_table, candidate.addr);
-                cur_fee = coin::value(fee_coin);
-            }
-        };
-
         let lockup_expired = get_reconfig_start_time_secs() >= stake_pool.locked_until_secs;
         spec {
-            assume cur_active + cur_pending_active + cur_reward + cur_fee <= MAX_U64;
-            assume cur_active + cur_pending_inactive + cur_pending_active + cur_reward + cur_fee <= MAX_U64;
+            assume cur_active + cur_pending_active + cur_reward <= MAX_U64;
+            assume cur_active + cur_pending_inactive + cur_pending_active + cur_reward <= MAX_U64;
         };
         let new_voting_power =
             cur_active
             + if (lockup_expired) { 0 } else { cur_pending_inactive }
             + cur_pending_active
-            + cur_reward + cur_fee;
+            + cur_reward;
 
         if (new_voting_power >= minimum_stake) {
             let config = *borrow_global<ValidatorConfig>(candidate.addr);
@@ -4078,7 +4003,7 @@ This function shouldn't abort.
     validator_perf: &ValidatorPerformance,
     pool_address: address,
     staking_config: &StakingConfig,
-) acquires StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorFees {
+) acquires StakePool, AptosCoinCapabilities, ValidatorConfig {
     let stake_pool = borrow_global_mut<StakePool>(pool_address);
     let validator_config = borrow_global<ValidatorConfig>(pool_address);
     let cur_validator_perf = vector::borrow(&validator_perf.validators, validator_config.validator_index);
@@ -4111,15 +4036,6 @@ This function shouldn't abort.
     // Pending active stake can now be active.
     coin::merge(&mut stake_pool.active, coin::extract_all(&mut stake_pool.pending_active));
 
-    // Additionally, distribute transaction fees.
-    if (features::collect_and_distribute_gas_fees()) {
-        let fees_table = &mut borrow_global_mut<ValidatorFees>(@aptos_framework).fees_table;
-        if (table::contains(fees_table, pool_address)) {
-            let coin = table::remove(fees_table, pool_address);
-            coin::merge(&mut stake_pool.active, coin);
-        };
-    };
-
     // Pending inactive stake is only fully unlocked and moved into inactive if the current lockup cycle has expired
     let current_lockup_expiration = stake_pool.locked_until_secs;
     if (get_reconfig_start_time_secs() >= current_lockup_expiration) {
@@ -4640,6 +4556,21 @@ Returns validator's next epoch voting power, including pending_active, active, a
 
 
 
+
+
+
+
+
fun spec_get_reconfig_start_time_secs(): u64 {
+   if (exists<reconfiguration_state::State>(@aptos_framework)) {
+       reconfiguration_state::spec_start_time_secs()
+   } else {
+       timestamp::spec_now_seconds()
+   }
+}
+
+ + + ### Resource `ValidatorSet` @@ -4781,51 +4712,6 @@ Returns validator's next epoch voting power, including pending_active, active, a - - -### Function `initialize_validator_fees` - - -
public(friend) fun initialize_validator_fees(aptos_framework: &signer)
-
- - - - -
let aptos_addr = signer::address_of(aptos_framework);
-aborts_if !system_addresses::is_aptos_framework_address(aptos_addr);
-aborts_if exists<ValidatorFees>(aptos_addr);
-ensures exists<ValidatorFees>(aptos_addr);
-
- - - - - -### Function `add_transaction_fee` - - -
public(friend) fun add_transaction_fee(validator_addr: address, fee: coin::Coin<aptos_coin::AptosCoin>)
-
- - - - -
aborts_if !exists<ValidatorFees>(@aptos_framework);
-let fees_table = global<ValidatorFees>(@aptos_framework).fees_table;
-let post post_fees_table = global<ValidatorFees>(@aptos_framework).fees_table;
-let collected_fee = table::spec_get(fees_table, validator_addr);
-let post post_collected_fee = table::spec_get(post_fees_table, validator_addr);
-ensures if (table::spec_contains(fees_table, validator_addr)) {
-    post_collected_fee.value == collected_fee.value + fee.value
-} else {
-    table::spec_contains(post_fees_table, validator_addr) &&
-    table::spec_get(post_fees_table, validator_addr) == fee
-};
-
- - - ### Function `get_validator_state` @@ -5705,7 +5591,6 @@ Returns validator's next epoch voting power, including pending_active, active, a requires exists<StakingConfig>(@aptos_framework); requires exists<StakingRewardsConfig>(@aptos_framework) || !features::spec_periodical_reward_rate_decrease_enabled(); requires exists<timestamp::CurrentTimeMicroseconds>(@aptos_framework); - requires exists<ValidatorFees>(@aptos_framework); }
@@ -5800,16 +5685,9 @@ Returns validator's next epoch voting power, including pending_active, active, a let post post_stake_pool = global<StakePool>(pool_address); let post post_active_value = post_stake_pool.active.value; let post post_pending_inactive_value = post_stake_pool.pending_inactive.value; -let fees_table = global<ValidatorFees>(@aptos_framework).fees_table; -let post post_fees_table = global<ValidatorFees>(@aptos_framework).fees_table; let post post_inactive_value = post_stake_pool.inactive.value; ensures post_stake_pool.pending_active.value == 0; -ensures if (features::spec_is_enabled(features::COLLECT_AND_DISTRIBUTE_GAS_FEES) && table::spec_contains(fees_table, pool_address)) { - !table::spec_contains(post_fees_table, pool_address) && - post_active_value == stake_pool.active.value + rewards_amount_1 + stake_pool.pending_active.value + table::spec_get(fees_table, pool_address).value -} else { - post_active_value == stake_pool.active.value + rewards_amount_1 + stake_pool.pending_active.value -}; +ensures post_active_value == stake_pool.active.value + rewards_amount_1 + stake_pool.pending_active.value; ensures if (spec_get_reconfig_start_time_secs() >= stake_pool.locked_until_secs) { post_pending_inactive_value == 0 && post_inactive_value == stake_pool.inactive.value + stake_pool.pending_inactive.value + rewards_amount_2 @@ -5831,7 +5709,6 @@ Returns validator's next epoch voting power, including pending_active, active, a aborts_if !exists<ValidatorConfig>(pool_address); aborts_if global<ValidatorConfig>(pool_address).validator_index >= len(validator_perf.validators); let aptos_addr = type_info::type_of<AptosCoin>().account_address; - aborts_if !exists<ValidatorFees>(aptos_addr); let stake_pool = global<StakePool>(pool_address); include DistributeRewardsAbortsIf {stake: stake_pool.active}; include DistributeRewardsAbortsIf {stake: stake_pool.pending_inactive}; @@ -5868,21 +5745,6 @@ Returns validator's next epoch voting power, including pending_active, active, a - - - - -
fun spec_get_reconfig_start_time_secs(): u64 {
-   if (exists<reconfiguration_state::State>(@aptos_framework)) {
-       reconfiguration_state::spec_start_time_secs()
-   } else {
-       timestamp::spec_now_seconds()
-   }
-}
-
- - - ### Function `calculate_rewards_amount` diff --git a/aptos-move/framework/aptos-framework/doc/staking_contract.md b/aptos-move/framework/aptos-framework/doc/staking_contract.md index 6376f194023f4..9327ed0574444 100644 --- a/aptos-move/framework/aptos-framework/doc/staking_contract.md +++ b/aptos-move/framework/aptos-framework/doc/staking_contract.md @@ -3597,7 +3597,6 @@ a staking_contract exists for the staker/operator pair. requires exists<staking_config::StakingRewardsConfig>( @aptos_framework ) || !std::features::spec_periodical_reward_rate_decrease_enabled(); - requires exists<stake::ValidatorFees>(@aptos_framework); requires exists<aptos_framework::timestamp::CurrentTimeMicroseconds>(@aptos_framework); requires exists<stake::AptosCoinCapabilities>(@aptos_framework); } diff --git a/aptos-move/framework/aptos-framework/doc/transaction_fee.md b/aptos-move/framework/aptos-framework/doc/transaction_fee.md index 09e76f34e14db..b672fe413d52e 100644 --- a/aptos-move/framework/aptos-framework/doc/transaction_fee.md +++ b/aptos-move/framework/aptos-framework/doc/transaction_fee.md @@ -9,39 +9,29 @@ This module provides an interface to burn or collect and redistribute transactio - [Resource `AptosCoinCapabilities`](#0x1_transaction_fee_AptosCoinCapabilities) - [Resource `AptosFABurnCapabilities`](#0x1_transaction_fee_AptosFABurnCapabilities) - [Resource `AptosCoinMintCapability`](#0x1_transaction_fee_AptosCoinMintCapability) -- [Resource `CollectedFeesPerBlock`](#0x1_transaction_fee_CollectedFeesPerBlock) - [Struct `FeeStatement`](#0x1_transaction_fee_FeeStatement) +- [Resource `CollectedFeesPerBlock`](#0x1_transaction_fee_CollectedFeesPerBlock) - [Constants](#@Constants_0) -- [Function `initialize_fee_collection_and_distribution`](#0x1_transaction_fee_initialize_fee_collection_and_distribution) -- [Function `is_fees_collection_enabled`](#0x1_transaction_fee_is_fees_collection_enabled) -- [Function `upgrade_burn_percentage`](#0x1_transaction_fee_upgrade_burn_percentage) -- [Function `register_proposer_for_fee_collection`](#0x1_transaction_fee_register_proposer_for_fee_collection) -- [Function `burn_coin_fraction`](#0x1_transaction_fee_burn_coin_fraction) -- [Function `process_collected_fees`](#0x1_transaction_fee_process_collected_fees) - [Function `burn_fee`](#0x1_transaction_fee_burn_fee) - [Function `mint_and_refund`](#0x1_transaction_fee_mint_and_refund) -- [Function `collect_fee`](#0x1_transaction_fee_collect_fee) - [Function `store_aptos_coin_burn_cap`](#0x1_transaction_fee_store_aptos_coin_burn_cap) - [Function `convert_to_aptos_fa_burn_ref`](#0x1_transaction_fee_convert_to_aptos_fa_burn_ref) - [Function `store_aptos_coin_mint_cap`](#0x1_transaction_fee_store_aptos_coin_mint_cap) -- [Function `initialize_storage_refund`](#0x1_transaction_fee_initialize_storage_refund) - [Function `emit_fee_statement`](#0x1_transaction_fee_emit_fee_statement) +- [Function `initialize_fee_collection_and_distribution`](#0x1_transaction_fee_initialize_fee_collection_and_distribution) +- [Function `upgrade_burn_percentage`](#0x1_transaction_fee_upgrade_burn_percentage) +- [Function `initialize_storage_refund`](#0x1_transaction_fee_initialize_storage_refund) - [Specification](#@Specification_1) - [High-level Requirements](#high-level-req) - [Module-level Specification](#module-level-spec) - [Resource `CollectedFeesPerBlock`](#@Specification_1_CollectedFeesPerBlock) - - [Function `initialize_fee_collection_and_distribution`](#@Specification_1_initialize_fee_collection_and_distribution) - - [Function `upgrade_burn_percentage`](#@Specification_1_upgrade_burn_percentage) - - [Function `register_proposer_for_fee_collection`](#@Specification_1_register_proposer_for_fee_collection) - - [Function `burn_coin_fraction`](#@Specification_1_burn_coin_fraction) - - [Function `process_collected_fees`](#@Specification_1_process_collected_fees) - [Function `burn_fee`](#@Specification_1_burn_fee) - [Function `mint_and_refund`](#@Specification_1_mint_and_refund) - - [Function `collect_fee`](#@Specification_1_collect_fee) - [Function `store_aptos_coin_burn_cap`](#@Specification_1_store_aptos_coin_burn_cap) - [Function `store_aptos_coin_mint_cap`](#@Specification_1_store_aptos_coin_mint_cap) - - [Function `initialize_storage_refund`](#@Specification_1_initialize_storage_refund) - [Function `emit_fee_statement`](#@Specification_1_emit_fee_statement) + - [Function `initialize_fee_collection_and_distribution`](#@Specification_1_initialize_fee_collection_and_distribution) + - [Function `initialize_storage_refund`](#@Specification_1_initialize_storage_refund)
use 0x1::aptos_account;
@@ -53,7 +43,6 @@ This module provides an interface to burn or collect and redistribute transactio
 use 0x1::fungible_asset;
 use 0x1::option;
 use 0x1::signer;
-use 0x1::stake;
 use 0x1::system_addresses;
 
@@ -141,47 +130,6 @@ Stores mint capability to mint the refunds. - - - - -## Resource `CollectedFeesPerBlock` - -Stores information about the block proposer and the amount of fees -collected when executing the block. - - -
struct CollectedFeesPerBlock has key
-
- - - -
-Fields - - -
-
-amount: coin::AggregatableCoin<aptos_coin::AptosCoin> -
-
- -
-
-proposer: option::Option<address> -
-
- -
-
-burn_percentage: u8 -
-
- -
-
- -
@@ -255,293 +203,93 @@ This is meant to emitted as a module event. - - -## Constants - - - - -Gas fees are already being collected and the struct holding -information about collected amounts is already published. - - -
const EALREADY_COLLECTING_FEES: u64 = 1;
-
- - - - - - - -
const EFA_GAS_CHARGING_NOT_ENABLED: u64 = 5;
-
- - - - - -The burn percentage is out of range [0, 100]. - - -
const EINVALID_BURN_PERCENTAGE: u64 = 3;
-
- - - - - -No longer supported. - - -
const ENO_LONGER_SUPPORTED: u64 = 4;
-
- - - - - -## Function `initialize_fee_collection_and_distribution` - -Initializes the resource storing information about gas fees collection and -distribution. Should be called by on-chain governance. - - -
public fun initialize_fee_collection_and_distribution(aptos_framework: &signer, burn_percentage: u8)
-
- - - -
-Implementation - - -
public fun initialize_fee_collection_and_distribution(aptos_framework: &signer, burn_percentage: u8) {
-    system_addresses::assert_aptos_framework(aptos_framework);
-    assert!(
-        !exists<CollectedFeesPerBlock>(@aptos_framework),
-        error::already_exists(EALREADY_COLLECTING_FEES)
-    );
-    assert!(burn_percentage <= 100, error::out_of_range(EINVALID_BURN_PERCENTAGE));
-
-    // Make sure stakng module is aware of transaction fees collection.
-    stake::initialize_validator_fees(aptos_framework);
-
-    // Initially, no fees are collected and the block proposer is not set.
-    let collected_fees = CollectedFeesPerBlock {
-        amount: coin::initialize_aggregatable_coin(aptos_framework),
-        proposer: option::none(),
-        burn_percentage,
-    };
-    move_to(aptos_framework, collected_fees);
-}
-
- - - -
- - - -## Function `is_fees_collection_enabled` - - - -
fun is_fees_collection_enabled(): bool
-
- - - -
-Implementation - - -
fun is_fees_collection_enabled(): bool {
-    exists<CollectedFeesPerBlock>(@aptos_framework)
-}
-
- - - -
- - + -## Function `upgrade_burn_percentage` +## Resource `CollectedFeesPerBlock` -Sets the burn percentage for collected fees to a new value. Should be called by on-chain governance. +DEPRECATED: Stores information about the block proposer and the amount of fees +collected when executing the block. -
public fun upgrade_burn_percentage(aptos_framework: &signer, new_burn_percentage: u8)
+
#[deprecated]
+struct CollectedFeesPerBlock has key
 
-Implementation +Fields -
public fun upgrade_burn_percentage(
-    aptos_framework: &signer,
-    new_burn_percentage: u8
-) acquires AptosCoinCapabilities, CollectedFeesPerBlock {
-    system_addresses::assert_aptos_framework(aptos_framework);
-    assert!(new_burn_percentage <= 100, error::out_of_range(EINVALID_BURN_PERCENTAGE));
+
+
+amount: coin::AggregatableCoin<aptos_coin::AptosCoin> +
+
- // Prior to upgrading the burn percentage, make sure to process collected - // fees. Otherwise we would use the new (incorrect) burn_percentage when - // processing fees later! - process_collected_fees(); +
+
+proposer: option::Option<address> +
+
- if (is_fees_collection_enabled()) { - // Upgrade has no effect unless fees are being collected. - let burn_percentage = &mut borrow_global_mut<CollectedFeesPerBlock>(@aptos_framework).burn_percentage; - *burn_percentage = new_burn_percentage - } -} -
+ +
+burn_percentage: u8 +
+
+
+
- - -## Function `register_proposer_for_fee_collection` - -Registers the proposer of the block for gas fees collection. This function -can only be called at the beginning of the block. - - -
public(friend) fun register_proposer_for_fee_collection(proposer_addr: address)
-
- - - -
-Implementation - - -
public(friend) fun register_proposer_for_fee_collection(proposer_addr: address) acquires CollectedFeesPerBlock {
-    if (is_fees_collection_enabled()) {
-        let collected_fees = borrow_global_mut<CollectedFeesPerBlock>(@aptos_framework);
-        let _ = option::swap_or_fill(&mut collected_fees.proposer, proposer_addr);
-    }
-}
-
- - + -
+## Constants - -## Function `burn_coin_fraction` + -Burns a specified fraction of the coin. +Gas fees are already being collected and the struct holding +information about collected amounts is already published. -
fun burn_coin_fraction(coin: &mut coin::Coin<aptos_coin::AptosCoin>, burn_percentage: u8)
+
const EALREADY_COLLECTING_FEES: u64 = 1;
 
-
-Implementation + -
fun burn_coin_fraction(coin: &mut Coin<AptosCoin>, burn_percentage: u8) acquires AptosCoinCapabilities {
-    assert!(burn_percentage <= 100, error::out_of_range(EINVALID_BURN_PERCENTAGE));
 
-    let collected_amount = coin::value(coin);
-    spec {
-        // We assume that `burn_percentage * collected_amount` does not overflow.
-        assume burn_percentage * collected_amount <= MAX_U64;
-    };
-    let amount_to_burn = (burn_percentage as u64) * collected_amount / 100;
-    if (amount_to_burn > 0) {
-        let coin_to_burn = coin::extract(coin, amount_to_burn);
-        coin::burn(
-            coin_to_burn,
-            &borrow_global<AptosCoinCapabilities>(@aptos_framework).burn_cap,
-        );
-    }
-}
+
const EFA_GAS_CHARGING_NOT_ENABLED: u64 = 5;
 
-
- - - -## Function `process_collected_fees` + -Calculates the fee which should be distributed to the block proposer at the -end of an epoch, and records it in the system. This function can only be called -at the beginning of the block or during reconfiguration. +The burn percentage is out of range [0, 100]. -
public(friend) fun process_collected_fees()
+
const EINVALID_BURN_PERCENTAGE: u64 = 3;
 
-
-Implementation - - -
public(friend) fun process_collected_fees() acquires AptosCoinCapabilities, CollectedFeesPerBlock {
-    if (!is_fees_collection_enabled()) {
-        return
-    };
-    let collected_fees = borrow_global_mut<CollectedFeesPerBlock>(@aptos_framework);
-
-    // If there are no collected fees, only unset the proposer. See the rationale for
-    // setting proposer to option::none() below.
-    if (coin::is_aggregatable_coin_zero(&collected_fees.amount)) {
-        if (option::is_some(&collected_fees.proposer)) {
-            let _ = option::extract(&mut collected_fees.proposer);
-        };
-        return
-    };
+
 
-    // Otherwise get the collected fee, and check if it can distributed later.
-    let coin = coin::drain_aggregatable_coin(&mut collected_fees.amount);
-    if (option::is_some(&collected_fees.proposer)) {
-        // Extract the address of proposer here and reset it to option::none(). This
-        // is particularly useful to avoid any undesired side-effects where coins are
-        // collected but never distributed or distributed to the wrong account.
-        // With this design, processing collected fees enforces that all fees will be burnt
-        // unless the proposer is specified in the block prologue. When we have a governance
-        // proposal that triggers reconfiguration, we distribute pending fees and burn the
-        // fee for the proposal. Otherwise, that fee would be leaked to the next block.
-        let proposer = option::extract(&mut collected_fees.proposer);
-
-        // Since the block can be produced by the VM itself, we have to make sure we catch
-        // this case.
-        if (proposer == @vm_reserved) {
-            burn_coin_fraction(&mut coin, 100);
-            coin::destroy_zero(coin);
-            return
-        };
+No longer supported.
 
-        burn_coin_fraction(&mut coin, collected_fees.burn_percentage);
-        stake::add_transaction_fee(proposer, coin);
-        return
-    };
 
-    // If checks did not pass, simply burn all collected coins and return none.
-    burn_coin_fraction(&mut coin, 100);
-    coin::destroy_zero(coin)
-}
+
const ENO_LONGER_SUPPORTED: u64 = 4;
 
-
- ## Function `burn_fee` @@ -608,37 +356,6 @@ Mint refund in epilogue. - - - - -## Function `collect_fee` - -Collect transaction fees in epilogue. - - -
public(friend) fun collect_fee(account: address, fee: u64)
-
- - - -
-Implementation - - -
public(friend) fun collect_fee(account: address, fee: u64) acquires CollectedFeesPerBlock {
-    let collected_fees = borrow_global_mut<CollectedFeesPerBlock>(@aptos_framework);
-
-    // Here, we are always optimistic and always collect fees. If the proposer is not set,
-    // or we cannot redistribute fees later for some reason (e.g. account cannot receive AptoCoin)
-    // we burn them all at once. This way we avoid having a check for every transaction epilogue.
-    let collected_amount = &mut collected_fees.amount;
-    coin::collect_into_aggregatable_coin<AptosCoin>(account, fee, collected_amount);
-}
-
- - -
@@ -729,14 +446,39 @@ Only called during genesis. - + -## Function `initialize_storage_refund` +## Function `emit_fee_statement` +
fun emit_fee_statement(fee_statement: transaction_fee::FeeStatement)
+
+ + + +
+Implementation + + +
fun emit_fee_statement(fee_statement: FeeStatement) {
+    event::emit(fee_statement)
+}
+
+ + + +
+ + + +## Function `initialize_fee_collection_and_distribution` + +DEPRECATED + +
#[deprecated]
-public fun initialize_storage_refund(_: &signer)
+public fun initialize_fee_collection_and_distribution(_aptos_framework: &signer, _burn_percentage: u8)
 
@@ -745,7 +487,7 @@ Only called during genesis. Implementation -
public fun initialize_storage_refund(_: &signer) {
+
public fun initialize_fee_collection_and_distribution(_aptos_framework: &signer, _burn_percentage: u8) {
     abort error::not_implemented(ENO_LONGER_SUPPORTED)
 }
 
@@ -754,13 +496,15 @@ Only called during genesis. - + -## Function `emit_fee_statement` +## Function `upgrade_burn_percentage` +DEPRECATED -
fun emit_fee_statement(fee_statement: transaction_fee::FeeStatement)
+
#[deprecated]
+public fun upgrade_burn_percentage(_aptos_framework: &signer, _new_burn_percentage: u8)
 
@@ -769,8 +513,36 @@ Only called during genesis. Implementation -
fun emit_fee_statement(fee_statement: FeeStatement) {
-    event::emit(fee_statement)
+
public fun upgrade_burn_percentage(
+    _aptos_framework: &signer,
+    _new_burn_percentage: u8
+) {
+    abort error::not_implemented(ENO_LONGER_SUPPORTED)
+}
+
+ + + + + + + +## Function `initialize_storage_refund` + + + +
#[deprecated]
+public fun initialize_storage_refund(_: &signer)
+
+ + + +
+Implementation + + +
public fun initialize_storage_refund(_: &signer) {
+    abort error::not_implemented(ENO_LONGER_SUPPORTED)
 }
 
@@ -865,7 +637,8 @@ Only called during genesis. ### Resource `CollectedFeesPerBlock` -
struct CollectedFeesPerBlock has key
+
#[deprecated]
+struct CollectedFeesPerBlock has key
 
@@ -899,178 +672,6 @@ Only called during genesis. - - -### Function `initialize_fee_collection_and_distribution` - - -
public fun initialize_fee_collection_and_distribution(aptos_framework: &signer, burn_percentage: u8)
-
- - - - -
// This enforces high-level requirement 2:
-aborts_if exists<CollectedFeesPerBlock>(@aptos_framework);
-aborts_if burn_percentage > 100;
-let aptos_addr = signer::address_of(aptos_framework);
-// This enforces high-level requirement 3:
-aborts_if !system_addresses::is_aptos_framework_address(aptos_addr);
-aborts_if exists<ValidatorFees>(aptos_addr);
-include system_addresses::AbortsIfNotAptosFramework { account: aptos_framework };
-include aggregator_factory::CreateAggregatorInternalAbortsIf;
-aborts_if exists<CollectedFeesPerBlock>(aptos_addr);
-ensures exists<ValidatorFees>(aptos_addr);
-ensures exists<CollectedFeesPerBlock>(aptos_addr);
-
- - - - - -### Function `upgrade_burn_percentage` - - -
public fun upgrade_burn_percentage(aptos_framework: &signer, new_burn_percentage: u8)
-
- - - - -
aborts_if new_burn_percentage > 100;
-let aptos_addr = signer::address_of(aptos_framework);
-aborts_if !system_addresses::is_aptos_framework_address(aptos_addr);
-// This enforces high-level requirement 5 and high-level requirement 6:
-include ProcessCollectedFeesRequiresAndEnsures;
-ensures exists<CollectedFeesPerBlock>(@aptos_framework) ==>
-    global<CollectedFeesPerBlock>(@aptos_framework).burn_percentage == new_burn_percentage;
-
- - - - - -### Function `register_proposer_for_fee_collection` - - -
public(friend) fun register_proposer_for_fee_collection(proposer_addr: address)
-
- - - - -
aborts_if false;
-// This enforces high-level requirement 6:
-ensures is_fees_collection_enabled() ==>
-    option::spec_borrow(global<CollectedFeesPerBlock>(@aptos_framework).proposer) == proposer_addr;
-
- - - - - -### Function `burn_coin_fraction` - - -
fun burn_coin_fraction(coin: &mut coin::Coin<aptos_coin::AptosCoin>, burn_percentage: u8)
-
- - - - -
requires burn_percentage <= 100;
-requires exists<AptosCoinCapabilities>(@aptos_framework);
-requires exists<CoinInfo<AptosCoin>>(@aptos_framework);
-let amount_to_burn = (burn_percentage * coin::value(coin)) / 100;
-include amount_to_burn > 0 ==> coin::CoinSubAbortsIf<AptosCoin> { amount: amount_to_burn };
-ensures coin.value == old(coin).value - amount_to_burn;
-
- - - - - - - -
fun collectedFeesAggregator(): AggregatableCoin<AptosCoin> {
-   global<CollectedFeesPerBlock>(@aptos_framework).amount
-}
-
- - - - - - - -
schema RequiresCollectedFeesPerValueLeqBlockAptosSupply {
-    let maybe_supply = coin::get_coin_supply_opt<AptosCoin>();
-    requires
-        (is_fees_collection_enabled() && option::is_some(maybe_supply)) ==>
-            (aggregator::spec_aggregator_get_val(global<CollectedFeesPerBlock>(@aptos_framework).amount.value) <=
-                optional_aggregator::optional_aggregator_value(
-                    option::spec_borrow(coin::get_coin_supply_opt<AptosCoin>())
-                ));
-}
-
- - - - - - - -
schema ProcessCollectedFeesRequiresAndEnsures {
-    requires exists<AptosCoinCapabilities>(@aptos_framework);
-    requires exists<stake::ValidatorFees>(@aptos_framework);
-    requires exists<CoinInfo<AptosCoin>>(@aptos_framework);
-    include RequiresCollectedFeesPerValueLeqBlockAptosSupply;
-    aborts_if false;
-    let collected_fees = global<CollectedFeesPerBlock>(@aptos_framework);
-    let post post_collected_fees = global<CollectedFeesPerBlock>(@aptos_framework);
-    let pre_amount = aggregator::spec_aggregator_get_val(collected_fees.amount.value);
-    let post post_amount = aggregator::spec_aggregator_get_val(post_collected_fees.amount.value);
-    let fees_table = global<stake::ValidatorFees>(@aptos_framework).fees_table;
-    let post post_fees_table = global<stake::ValidatorFees>(@aptos_framework).fees_table;
-    let proposer = option::spec_borrow(collected_fees.proposer);
-    let fee_to_add = pre_amount - pre_amount * collected_fees.burn_percentage / 100;
-    ensures is_fees_collection_enabled() ==> option::spec_is_none(post_collected_fees.proposer) && post_amount == 0;
-    ensures is_fees_collection_enabled() && aggregator::spec_read(collected_fees.amount.value) > 0 &&
-        option::spec_is_some(collected_fees.proposer) ==>
-        if (proposer != @vm_reserved) {
-            if (table::spec_contains(fees_table, proposer)) {
-                table::spec_get(post_fees_table, proposer).value == table::spec_get(
-                    fees_table,
-                    proposer
-                ).value + fee_to_add
-            } else {
-                table::spec_get(post_fees_table, proposer).value == fee_to_add
-            }
-        } else {
-            option::spec_is_none(post_collected_fees.proposer) && post_amount == 0
-        };
-}
-
- - - - - -### Function `process_collected_fees` - - -
public(friend) fun process_collected_fees()
-
- - - - -
// This enforces high-level requirement 6:
-include ProcessCollectedFeesRequiresAndEnsures;
-
- - - ### Function `burn_fee` @@ -1136,38 +737,6 @@ Only called during genesis. - - -### Function `collect_fee` - - -
public(friend) fun collect_fee(account: address, fee: u64)
-
- - - - -
pragma verify = false;
-let collected_fees = global<CollectedFeesPerBlock>(@aptos_framework).amount;
-let aggr = collected_fees.value;
-let coin_store = global<coin::CoinStore<AptosCoin>>(account);
-aborts_if !exists<CollectedFeesPerBlock>(@aptos_framework);
-aborts_if fee > 0 && !exists<coin::CoinStore<AptosCoin>>(account);
-aborts_if fee > 0 && coin_store.coin.value < fee;
-aborts_if fee > 0 && aggregator::spec_aggregator_get_val(aggr)
-    + fee > aggregator::spec_get_limit(aggr);
-aborts_if fee > 0 && aggregator::spec_aggregator_get_val(aggr)
-    + fee > MAX_U128;
-let post post_coin_store = global<coin::CoinStore<AptosCoin>>(account);
-let post post_collected_fees = global<CollectedFeesPerBlock>(@aptos_framework).amount;
-ensures post_coin_store.coin.value == coin_store.coin.value - fee;
-ensures aggregator::spec_aggregator_get_val(post_collected_fees.value) == aggregator::spec_aggregator_get_val(
-    aggr
-) + fee;
-
- - - ### Function `store_aptos_coin_burn_cap` @@ -1212,34 +781,45 @@ Aborts if + -### Function `initialize_storage_refund` +### Function `emit_fee_statement` -
#[deprecated]
-public fun initialize_storage_refund(_: &signer)
+
fun emit_fee_statement(fee_statement: transaction_fee::FeeStatement)
 
-Historical. Aborts. +Aborts if module event feature is not enabled. -
aborts_if true;
+
+
+### Function `initialize_fee_collection_and_distribution`
+
+
+
#[deprecated]
+public fun initialize_fee_collection_and_distribution(_aptos_framework: &signer, _burn_percentage: u8)
 
- -### Function `emit_fee_statement` + +### Function `initialize_storage_refund` -
fun emit_fee_statement(fee_statement: transaction_fee::FeeStatement)
+
+
#[deprecated]
+public fun initialize_storage_refund(_: &signer)
 
-Aborts if module event feature is not enabled. +Historical. Aborts. + + +
aborts_if true;
+
[move-book]: https://aptos.dev/move/book/SUMMARY diff --git a/aptos-move/framework/aptos-framework/doc/transaction_validation.md b/aptos-move/framework/aptos-framework/doc/transaction_validation.md index b21495159a7c3..c126406ef89b5 100644 --- a/aptos-move/framework/aptos-framework/doc/transaction_validation.md +++ b/aptos-move/framework/aptos-framework/doc/transaction_validation.md @@ -888,26 +888,11 @@ Called by the Adapter ); }; - let amount_to_burn = if (features::collect_and_distribute_gas_fees()) { - // TODO(gas): We might want to distinguish the refundable part of the charge and burn it or track - // it separately, so that we don't increase the total supply by refunding. - - // If transaction fees are redistributed to validators, collect them here for - // later redistribution. - transaction_fee::collect_fee(gas_payer, transaction_fee_amount); - 0 - } else { - // Otherwise, just burn the fee. - // TODO: this branch should be removed completely when transaction fee collection - // is tested and is fully proven to work well. - transaction_fee_amount - }; - - if (amount_to_burn > storage_fee_refunded) { - let burn_amount = amount_to_burn - storage_fee_refunded; + if (transaction_fee_amount > storage_fee_refunded) { + let burn_amount = transaction_fee_amount - storage_fee_refunded; transaction_fee::burn_fee(gas_payer, burn_amount); - } else if (amount_to_burn < storage_fee_refunded) { - let mint_amount = storage_fee_refunded - amount_to_burn; + } else if (transaction_fee_amount < storage_fee_refunded) { + let mint_amount = storage_fee_refunded - transaction_fee_amount; transaction_fee::mint_and_refund(gas_payer, mint_amount) }; }; @@ -1372,19 +1357,7 @@ Skip transaction_fee::burn_fee verification. aborts_if !exists<Account>(addr); aborts_if !(global<Account>(addr).sequence_number < MAX_U64); ensures account.sequence_number == pre_account.sequence_number + 1; - let collect_fee_enabled = features::spec_is_enabled(features::COLLECT_AND_DISTRIBUTE_GAS_FEES); - let collected_fees = global<CollectedFeesPerBlock>(@aptos_framework).amount; - let aggr = collected_fees.value; - let aggr_val = aggregator::spec_aggregator_get_val(aggr); - let aggr_lim = aggregator::spec_get_limit(aggr); - // This enforces high-level requirement 3: - aborts_if collect_fee_enabled && !exists<CollectedFeesPerBlock>(@aptos_framework); - aborts_if collect_fee_enabled && transaction_fee_amount > 0 && aggr_val + transaction_fee_amount > aggr_lim; - let amount_to_burn = if (collect_fee_enabled) { - 0 - } else { - transaction_fee_amount - storage_fee_refunded - }; + let amount_to_burn = transaction_fee_amount - storage_fee_refunded; let apt_addr = type_info::type_of<AptosCoin>().account_address; let maybe_apt_supply = global<CoinInfo<AptosCoin>>(apt_addr).supply; let total_supply_enabled = option::spec_is_some(maybe_apt_supply); @@ -1397,11 +1370,7 @@ Skip transaction_fee::burn_fee verification. aborts_if amount_to_burn > 0 && !exists<CoinInfo<AptosCoin>>(apt_addr); aborts_if amount_to_burn > 0 && total_supply_enabled && apt_supply_value < amount_to_burn; ensures total_supply_enabled ==> apt_supply_value - amount_to_burn == post_apt_supply_value; - let amount_to_mint = if (collect_fee_enabled) { - storage_fee_refunded - } else { - storage_fee_refunded - transaction_fee_amount - }; + let amount_to_mint = storage_fee_refunded - transaction_fee_amount; let total_supply = coin::supply<AptosCoin>; let post post_total_supply = coin::supply<AptosCoin>; aborts_if amount_to_mint > 0 && !exists<CoinStore<AptosCoin>>(addr); diff --git a/aptos-move/framework/aptos-framework/doc/version.md b/aptos-move/framework/aptos-framework/doc/version.md index c201f455c86f1..8505a6f3f18d2 100644 --- a/aptos-move/framework/aptos-framework/doc/version.md +++ b/aptos-move/framework/aptos-framework/doc/version.md @@ -358,11 +358,9 @@ Abort if resource already exists in @aptos_framwork when initializi
pragma verify_duration_estimate = 120;
-include transaction_fee::RequiresCollectedFeesPerValueLeqBlockAptosSupply;
 include staking_config::StakingRewardsConfigRequirement;
 requires chain_status::is_genesis();
 requires timestamp::spec_now_microseconds() >= reconfiguration::last_reconfiguration_time();
-requires exists<stake::ValidatorFees>(@aptos_framework);
 requires exists<CoinInfo<AptosCoin>>(@aptos_framework);
 aborts_if !exists<SetVersionCapability>(signer::address_of(account));
 aborts_if !exists<Version>(@aptos_framework);
diff --git a/aptos-move/framework/aptos-framework/sources/aptos_governance.spec.move b/aptos-move/framework/aptos-framework/sources/aptos_governance.spec.move
index 4c0189023816c..ab3c87c9b0c1e 100644
--- a/aptos-move/framework/aptos-framework/sources/aptos_governance.spec.move
+++ b/aptos-move/framework/aptos-framework/sources/aptos_governance.spec.move
@@ -138,7 +138,6 @@ spec aptos_framework::aptos_governance {
         use aptos_framework::chain_status;
         use aptos_framework::coin::CoinInfo;
         use aptos_framework::aptos_coin::AptosCoin;
-        use aptos_framework::transaction_fee;
         pragma verify = false; // TODO: set because of timeout (property proved).
         let addr = signer::address_of(aptos_framework);
         aborts_if addr != @aptos_framework;
@@ -146,9 +145,7 @@ spec aptos_framework::aptos_governance {
             framework: aptos_framework
         };
         include stake::GetReconfigStartTimeRequirement;
-        include transaction_fee::RequiresCollectedFeesPerValueLeqBlockAptosSupply;
         requires chain_status::is_operating();
-        requires exists(@aptos_framework);
         requires exists>(@aptos_framework);
         requires exists(@aptos_framework);
         include staking_config::StakingRewardsConfigRequirement;
@@ -578,7 +575,6 @@ spec aptos_framework::aptos_governance {
         use aptos_framework::chain_status;
         use aptos_framework::coin::CoinInfo;
         use aptos_framework::aptos_coin::AptosCoin;
-        use aptos_framework::transaction_fee;
         pragma verify = false; // TODO: set because of timeout (property proved).
         aborts_if !system_addresses::is_aptos_framework_address(signer::address_of(aptos_framework));
         include reconfiguration_with_dkg::FinishRequirement {
@@ -586,9 +582,7 @@ spec aptos_framework::aptos_governance {
         };
         include stake::GetReconfigStartTimeRequirement;
 
-        include transaction_fee::RequiresCollectedFeesPerValueLeqBlockAptosSupply;
         requires chain_status::is_operating();
-        requires exists(@aptos_framework);
         requires exists>(@aptos_framework);
         requires exists(@aptos_framework);
         include staking_config::StakingRewardsConfigRequirement;
diff --git a/aptos-move/framework/aptos-framework/sources/block.move b/aptos-move/framework/aptos-framework/sources/block.move
index 5899481316be7..0b8f96a5a1079 100644
--- a/aptos-move/framework/aptos-framework/sources/block.move
+++ b/aptos-move/framework/aptos-framework/sources/block.move
@@ -1,7 +1,6 @@
 /// This module defines a struct storing the metadata of the block and new block events.
 module aptos_framework::block {
     use std::error;
-    use std::features;
     use std::vector;
     use std::option;
     use aptos_std::table_with_length::{Self, TableWithLength};
@@ -16,7 +15,6 @@ module aptos_framework::block {
     use aptos_framework::state_storage;
     use aptos_framework::system_addresses;
     use aptos_framework::timestamp;
-    use aptos_framework::transaction_fee;
 
     friend aptos_framework::genesis;
 
@@ -202,15 +200,6 @@ module aptos_framework::block {
         };
         emit_new_block_event(vm, &mut block_metadata_ref.new_block_events, new_block_event, new_block_event_v2);
 
-        if (features::collect_and_distribute_gas_fees()) {
-            // Assign the fees collected from the previous block to the previous block proposer.
-            // If for any reason the fees cannot be assigned, this function burns the collected coins.
-            transaction_fee::process_collected_fees();
-            // Set the proposer of this block as the receiver of the fees, so that the fees for this
-            // block are assigned to the right account.
-            transaction_fee::register_proposer_for_fee_collection(proposer);
-        };
-
         // Performance scores have to be updated before the epoch transition as the transaction that triggers the
         // transition is the last block in the previous epoch.
         stake::update_performance_statistics(proposer_index, failed_proposer_indices);
diff --git a/aptos-move/framework/aptos-framework/sources/block.spec.move b/aptos-move/framework/aptos-framework/sources/block.spec.move
index 2a8d982bd8ed7..b2c5e749ddabc 100644
--- a/aptos-move/framework/aptos-framework/sources/block.spec.move
+++ b/aptos-move/framework/aptos-framework/sources/block.spec.move
@@ -127,7 +127,6 @@ spec aptos_framework::block {
         use aptos_framework::chain_status;
         use aptos_framework::coin::CoinInfo;
         use aptos_framework::aptos_coin::AptosCoin;
-        use aptos_framework::transaction_fee;
         use aptos_framework::staking_config;
 
         vm: signer;
@@ -145,9 +144,7 @@ spec aptos_framework::block {
         requires proposer == @vm_reserved || stake::spec_is_current_epoch_validator(proposer);
         requires (proposer == @vm_reserved) ==> (timestamp::spec_now_microseconds() == timestamp);
         requires (proposer != @vm_reserved) ==> (timestamp::spec_now_microseconds() < timestamp);
-        requires exists(@aptos_framework);
         requires exists>(@aptos_framework);
-        include transaction_fee::RequiresCollectedFeesPerValueLeqBlockAptosSupply;
         include staking_config::StakingRewardsConfigRequirement;
     }
 
diff --git a/aptos-move/framework/aptos-framework/sources/coin.move b/aptos-move/framework/aptos-framework/sources/coin.move
index 5f6598024d492..b2e9a6c8f3b19 100644
--- a/aptos-move/framework/aptos-framework/sources/coin.move
+++ b/aptos-move/framework/aptos-framework/sources/coin.move
@@ -9,7 +9,7 @@ module aptos_framework::coin {
 
     use aptos_framework::account;
     use aptos_framework::aggregator_factory;
-    use aptos_framework::aggregator::{Self, Aggregator};
+    use aptos_framework::aggregator::Aggregator;
     use aptos_framework::event::{Self, EventHandle};
     use aptos_framework::guid;
     use aptos_framework::optional_aggregator::{Self, OptionalAggregator};
@@ -122,9 +122,8 @@ module aptos_framework::coin {
         value: u64,
     }
 
-    /// Represents a coin with aggregator as its value. This allows to update
-    /// the coin in every transaction avoiding read-modify-write conflicts. Only
-    /// used for gas fees distribution by Aptos Framework (0x1).
+    #[deprecated]
+    /// DEPRECATED
     struct AggregatableCoin has store {
         /// Amount of aggregatable coin this address has.
         value: Aggregator,
@@ -556,93 +555,6 @@ module aptos_framework::coin {
         *allow_upgrades = allowed;
     }
 
-    //
-    //  Aggregatable coin functions
-    //
-
-    /// Creates a new aggregatable coin with value overflowing on `limit`. Note that this function can
-    /// only be called by Aptos Framework (0x1) account for now because of `create_aggregator`.
-    public(friend) fun initialize_aggregatable_coin(aptos_framework: &signer): AggregatableCoin {
-        let aggregator = aggregator_factory::create_aggregator(aptos_framework, MAX_U64);
-        AggregatableCoin {
-            value: aggregator,
-        }
-    }
-
-    /// Returns true if the value of aggregatable coin is zero.
-    public(friend) fun is_aggregatable_coin_zero(coin: &AggregatableCoin): bool {
-        let amount = aggregator::read(&coin.value);
-        amount == 0
-    }
-
-    /// Drains the aggregatable coin, setting it to zero and returning a standard coin.
-    public(friend) fun drain_aggregatable_coin(coin: &mut AggregatableCoin): Coin {
-        spec {
-            // TODO: The data invariant is not properly assumed from CollectedFeesPerBlock.
-            assume aggregator::spec_get_limit(coin.value) == MAX_U64;
-        };
-        let amount = aggregator::read(&coin.value);
-        assert!(amount <= MAX_U64, error::out_of_range(EAGGREGATABLE_COIN_VALUE_TOO_LARGE));
-        spec {
-            update aggregate_supply = aggregate_supply - amount;
-        };
-        aggregator::sub(&mut coin.value, amount);
-        spec {
-            update supply = supply + amount;
-        };
-        Coin {
-            value: (amount as u64),
-        }
-    }
-
-    /// Merges `coin` into aggregatable coin (`dst_coin`).
-    public(friend) fun merge_aggregatable_coin(
-        dst_coin: &mut AggregatableCoin,
-        coin: Coin
-    ) {
-        spec {
-            update supply = supply - coin.value;
-        };
-        let Coin { value } = coin;
-        let amount = (value as u128);
-        spec {
-            update aggregate_supply = aggregate_supply + amount;
-        };
-        aggregator::add(&mut dst_coin.value, amount);
-    }
-
-    /// Collects a specified amount of coin form an account into aggregatable coin.
-    public(friend) fun collect_into_aggregatable_coin(
-        account_addr: address,
-        amount: u64,
-        dst_coin: &mut AggregatableCoin,
-    ) acquires CoinStore, CoinConversionMap, CoinInfo, PairedCoinType {
-        // Skip collecting if amount is zero.
-        if (amount == 0) {
-            return
-        };
-
-        let (coin_amount_to_collect, fa_amount_to_collect) = calculate_amount_to_withdraw(
-            account_addr,
-            amount
-        );
-        let coin = if (coin_amount_to_collect > 0) {
-            let coin_store = borrow_global_mut>(account_addr);
-            extract(&mut coin_store.coin, coin_amount_to_collect)
-        } else {
-            zero()
-        };
-        if (fa_amount_to_collect > 0) {
-            let store_addr = primary_fungible_store::primary_store_address(
-                account_addr,
-                option::destroy_some(paired_metadata())
-            );
-            let fa = fungible_asset::withdraw_internal(store_addr, fa_amount_to_collect);
-            merge(&mut coin, fungible_asset_to_coin(fa));
-        };
-        merge_aggregatable_coin(dst_coin, coin);
-    }
-
     inline fun calculate_amount_to_withdraw(
         account_addr: address,
         amount: u64
@@ -1272,6 +1184,9 @@ module aptos_framework::coin {
         amount
     }
 
+    #[test_only]
+    use aptos_framework::aggregator;
+
     #[test_only]
     struct FakeMoney {}
 
@@ -1841,51 +1756,6 @@ module aptos_framework::coin {
         aggregator::destroy(value);
     }
 
-    #[test(framework = @aptos_framework)]
-    public entry fun test_collect_from_and_drain(
-        framework: signer,
-    ) acquires CoinInfo, CoinStore, CoinConversionMap, PairedCoinType {
-        let framework_addr = signer::address_of(&framework);
-        account::create_account_for_test(framework_addr);
-        let (burn_cap, freeze_cap, mint_cap) = initialize_and_register_fake_money(&framework, 1, true);
-
-        // Collect from coin store only.
-        let coins_minted = mint(100, &mint_cap);
-        deposit(framework_addr, coins_minted);
-        let aggregatable_coin = initialize_aggregatable_coin(&framework);
-        collect_into_aggregatable_coin(framework_addr, 50, &mut aggregatable_coin);
-
-        let fa_minted = coin_to_fungible_asset(mint(100, &mint_cap));
-        primary_fungible_store::deposit(framework_addr, fa_minted);
-        assert!(balance(framework_addr) == 150, 0);
-        assert!(*option::borrow(&supply()) == 200, 0);
-
-        // Collect from coin store and fungible store.
-        collect_into_aggregatable_coin(framework_addr, 100, &mut aggregatable_coin);
-
-        assert!(balance(framework_addr) == 50, 0);
-        maybe_convert_to_fungible_store(framework_addr);
-        // Collect from fungible store only.
-        collect_into_aggregatable_coin(framework_addr, 30, &mut aggregatable_coin);
-
-        // Check that aggregatable coin has the right amount.
-        let collected_coin = drain_aggregatable_coin(&mut aggregatable_coin);
-        assert!(is_aggregatable_coin_zero(&aggregatable_coin), 0);
-        assert!(value(&collected_coin) == 180, 0);
-
-        // Supply of coins should be unchanged, but the balance on the account should decrease.
-        assert!(balance(framework_addr) == 20, 0);
-        assert!(*option::borrow(&supply()) == 200, 0);
-
-        burn(collected_coin, &burn_cap);
-        destroy_aggregatable_coin_for_test(aggregatable_coin);
-        move_to(&framework, FakeMoneyCapabilities {
-            burn_cap,
-            freeze_cap,
-            mint_cap,
-        });
-    }
-
     #[test_only]
     fun deposit_to_coin_store(account_addr: address, coin: Coin) acquires CoinStore {
         assert!(
diff --git a/aptos-move/framework/aptos-framework/sources/coin.spec.move b/aptos-move/framework/aptos-framework/sources/coin.spec.move
index 2564bc0daa8c6..32bdc6645b3de 100644
--- a/aptos-move/framework/aptos-framework/sources/coin.spec.move
+++ b/aptos-move/framework/aptos-framework/sources/coin.spec.move
@@ -578,46 +578,4 @@ spec aptos_framework::coin {
         aborts_if coin_store.frozen;
         aborts_if balance < amount;
     }
-
-    spec initialize_aggregatable_coin(aptos_framework: &signer): AggregatableCoin {
-        include system_addresses::AbortsIfNotAptosFramework { account: aptos_framework };
-        include aggregator_factory::CreateAggregatorInternalAbortsIf;
-    }
-
-    spec is_aggregatable_coin_zero(coin: &AggregatableCoin): bool {
-        aborts_if false;
-        ensures result == (aggregator::spec_read(coin.value) == 0);
-    }
-
-    spec drain_aggregatable_coin(coin: &mut AggregatableCoin): Coin {
-        aborts_if aggregator::spec_read(coin.value) > MAX_U64;
-        ensures result.value == aggregator::spec_aggregator_get_val(old(coin).value);
-    }
-
-    spec merge_aggregatable_coin(dst_coin: &mut AggregatableCoin, coin: Coin) {
-        let aggr = dst_coin.value;
-        let post p_aggr = dst_coin.value;
-        aborts_if aggregator::spec_aggregator_get_val(aggr)
-            + coin.value > aggregator::spec_get_limit(aggr);
-        aborts_if aggregator::spec_aggregator_get_val(aggr)
-            + coin.value > MAX_U128;
-        ensures aggregator::spec_aggregator_get_val(aggr) + coin.value == aggregator::spec_aggregator_get_val(p_aggr);
-    }
-
-    spec collect_into_aggregatable_coin(account_addr: address, amount: u64, dst_coin: &mut AggregatableCoin) {
-        // TODO(fa_migration)
-        pragma verify = false;
-        let aggr = dst_coin.value;
-        let post p_aggr = dst_coin.value;
-        let coin_store = global>(account_addr);
-        let post p_coin_store = global>(account_addr);
-        aborts_if amount > 0 && !exists>(account_addr);
-        aborts_if amount > 0 && coin_store.coin.value < amount;
-        aborts_if amount > 0 && aggregator::spec_aggregator_get_val(aggr)
-            + amount > aggregator::spec_get_limit(aggr);
-        aborts_if amount > 0 && aggregator::spec_aggregator_get_val(aggr)
-            + amount > MAX_U128;
-        ensures aggregator::spec_aggregator_get_val(aggr) + amount == aggregator::spec_aggregator_get_val(p_aggr);
-        ensures coin_store.coin.value - amount == p_coin_store.coin.value;
-    }
 }
diff --git a/aptos-move/framework/aptos-framework/sources/configs/consensus_config.spec.move b/aptos-move/framework/aptos-framework/sources/configs/consensus_config.spec.move
index f0360989f47a6..182c19faa46d1 100644
--- a/aptos-move/framework/aptos-framework/sources/configs/consensus_config.spec.move
+++ b/aptos-move/framework/aptos-framework/sources/configs/consensus_config.spec.move
@@ -47,15 +47,12 @@ spec aptos_framework::consensus_config {
         use aptos_framework::chain_status;
         use aptos_framework::timestamp;
         use std::signer;
-        use aptos_framework::stake;
         use aptos_framework::coin::CoinInfo;
         use aptos_framework::aptos_coin::AptosCoin;
-        use aptos_framework::transaction_fee;
         use aptos_framework::staking_config;
 
         // TODO: set because of timeout (property proved)
         pragma verify_duration_estimate = 600;
-        include transaction_fee::RequiresCollectedFeesPerValueLeqBlockAptosSupply;
         include staking_config::StakingRewardsConfigRequirement;
         let addr = signer::address_of(account);
         /// [high-level-req-2]
@@ -66,7 +63,6 @@ spec aptos_framework::consensus_config {
 
         requires chain_status::is_genesis();
         requires timestamp::spec_now_microseconds() >= reconfiguration::last_reconfiguration_time();
-        requires exists(@aptos_framework);
         requires exists>(@aptos_framework);
         ensures global(@aptos_framework).config == config;
     }
diff --git a/aptos-move/framework/aptos-framework/sources/configs/execution_config.spec.move b/aptos-move/framework/aptos-framework/sources/configs/execution_config.spec.move
index 4b04d757f2fdb..381e550a92b06 100644
--- a/aptos-move/framework/aptos-framework/sources/configs/execution_config.spec.move
+++ b/aptos-move/framework/aptos-framework/sources/configs/execution_config.spec.move
@@ -10,18 +10,14 @@ spec aptos_framework::execution_config {
         use aptos_framework::timestamp;
         use std::signer;
         use std::features;
-        use aptos_framework::transaction_fee;
         use aptos_framework::chain_status;
-        use aptos_framework::stake;
         use aptos_framework::staking_config;
         use aptos_framework::aptos_coin;
 
         // TODO: set because of timeout (property proved)
         pragma verify_duration_estimate = 600;
         let addr = signer::address_of(account);
-        include transaction_fee::RequiresCollectedFeesPerValueLeqBlockAptosSupply;
         requires chain_status::is_genesis();
-        requires exists(@aptos_framework);
         requires exists(@aptos_framework);
         requires len(config) > 0;
         include features::spec_periodical_reward_rate_decrease_enabled() ==> staking_config::StakingRewardsConfigEnabledRequirement;
diff --git a/aptos-move/framework/aptos-framework/sources/configs/gas_schedule.spec.move b/aptos-move/framework/aptos-framework/sources/configs/gas_schedule.spec.move
index 7ce238f7b9959..ee57cd4c1c3c2 100644
--- a/aptos-move/framework/aptos-framework/sources/configs/gas_schedule.spec.move
+++ b/aptos-move/framework/aptos-framework/sources/configs/gas_schedule.spec.move
@@ -49,19 +49,15 @@ spec aptos_framework::gas_schedule {
     spec set_gas_schedule(aptos_framework: &signer, gas_schedule_blob: vector) {
         use std::signer;
         use aptos_framework::util;
-        use aptos_framework::stake;
         use aptos_framework::coin::CoinInfo;
         use aptos_framework::aptos_coin::AptosCoin;
-        use aptos_framework::transaction_fee;
         use aptos_framework::staking_config;
         use aptos_framework::chain_status;
 
         // TODO: set because of timeout (property proved)
         pragma verify_duration_estimate = 600;
-        requires exists(@aptos_framework);
         requires exists>(@aptos_framework);
         requires chain_status::is_genesis();
-        include transaction_fee::RequiresCollectedFeesPerValueLeqBlockAptosSupply;
         include staking_config::StakingRewardsConfigRequirement;
 
         /// [high-level-req-2]
@@ -77,18 +73,14 @@ spec aptos_framework::gas_schedule {
     }
 
     spec set_storage_gas_config(aptos_framework: &signer, config: StorageGasConfig) {
-        use aptos_framework::stake;
         use aptos_framework::coin::CoinInfo;
         use aptos_framework::aptos_coin::AptosCoin;
-        use aptos_framework::transaction_fee;
         use aptos_framework::staking_config;
 
         // TODO: set because of timeout (property proved).
         pragma verify_duration_estimate = 600;
-        requires exists(@aptos_framework);
         requires exists>(@aptos_framework);
         include system_addresses::AbortsIfNotAptosFramework{ account: aptos_framework };
-        include transaction_fee::RequiresCollectedFeesPerValueLeqBlockAptosSupply;
         include staking_config::StakingRewardsConfigRequirement;
         aborts_if !exists(@aptos_framework);
         ensures global(@aptos_framework) == config;
diff --git a/aptos-move/framework/aptos-framework/sources/configs/version.spec.move b/aptos-move/framework/aptos-framework/sources/configs/version.spec.move
index 5ce2685d1158b..76cb72c5fad68 100644
--- a/aptos-move/framework/aptos-framework/sources/configs/version.spec.move
+++ b/aptos-move/framework/aptos-framework/sources/configs/version.spec.move
@@ -26,20 +26,16 @@ spec aptos_framework::version {
         use std::signer;
         use aptos_framework::chain_status;
         use aptos_framework::timestamp;
-        use aptos_framework::stake;
         use aptos_framework::coin::CoinInfo;
         use aptos_framework::aptos_coin::AptosCoin;
-        use aptos_framework::transaction_fee;
         use aptos_framework::staking_config;
         use aptos_framework::reconfiguration;
 
         // TODO: set because of timeout (property proved)
         pragma verify_duration_estimate = 120;
-        include transaction_fee::RequiresCollectedFeesPerValueLeqBlockAptosSupply;
         include staking_config::StakingRewardsConfigRequirement;
         requires chain_status::is_genesis();
         requires timestamp::spec_now_microseconds() >= reconfiguration::last_reconfiguration_time();
-        requires exists(@aptos_framework);
         requires exists>(@aptos_framework);
 
         aborts_if !exists(signer::address_of(account));
diff --git a/aptos-move/framework/aptos-framework/sources/genesis.spec.move b/aptos-move/framework/aptos-framework/sources/genesis.spec.move
index 439d72c81b43c..8378b5b4cfafe 100644
--- a/aptos-move/framework/aptos-framework/sources/genesis.spec.move
+++ b/aptos-move/framework/aptos-framework/sources/genesis.spec.move
@@ -157,10 +157,8 @@ spec aptos_framework::genesis {
         requires chain_status::is_operating();
         requires len(execution_config) > 0;
         requires exists(@aptos_framework);
-        requires exists(@aptos_framework);
         requires exists>(@aptos_framework);
         include CompareTimeRequires;
-        include transaction_fee::RequiresCollectedFeesPerValueLeqBlockAptosSupply;
     }
 
     spec schema CompareTimeRequires {
diff --git a/aptos-move/framework/aptos-framework/sources/reconfiguration.move b/aptos-move/framework/aptos-framework/sources/reconfiguration.move
index 04a48b6466e75..6bf02a1d1b0f5 100644
--- a/aptos-move/framework/aptos-framework/sources/reconfiguration.move
+++ b/aptos-move/framework/aptos-framework/sources/reconfiguration.move
@@ -13,7 +13,6 @@ module aptos_framework::reconfiguration {
     use aptos_framework::chain_status;
     use aptos_framework::reconfiguration_state;
     use aptos_framework::storage_gas;
-    use aptos_framework::transaction_fee;
 
     friend aptos_framework::aptos_governance;
     friend aptos_framework::block;
@@ -131,20 +130,6 @@ module aptos_framework::reconfiguration {
 
         reconfiguration_state::on_reconfig_start();
 
-        // Reconfiguration "forces the block" to end, as mentioned above. Therefore, we must process the collected fees
-        // explicitly so that staking can distribute them.
-        //
-        // This also handles the case when a validator is removed due to the governance proposal. In particular, removing
-        // the validator causes a reconfiguration. We explicitly process fees, i.e. we drain aggregatable coin and populate
-        // the fees table, prior to calling `on_new_epoch()`. That call, in turn, distributes transaction fees for all active
-        // and pending_inactive validators, which include any validator that is to be removed.
-        if (features::collect_and_distribute_gas_fees()) {
-            // All transactions after reconfiguration are Retry. Therefore, when the next
-            // block starts and tries to assign/burn collected fees it will be just 0 and
-            // nothing will be assigned.
-            transaction_fee::process_collected_fees();
-        };
-
         // Call stake to compute the new validator set and distribute rewards and transaction fees.
         stake::on_new_epoch();
         storage_gas::on_reconfig();
diff --git a/aptos-move/framework/aptos-framework/sources/reconfiguration.spec.move b/aptos-move/framework/aptos-framework/sources/reconfiguration.spec.move
index 4bea1460fdb54..78aae7ea28d0d 100644
--- a/aptos-move/framework/aptos-framework/sources/reconfiguration.spec.move
+++ b/aptos-move/framework/aptos-framework/sources/reconfiguration.spec.move
@@ -127,19 +127,16 @@ spec aptos_framework::reconfiguration {
 
     spec reconfigure {
         use aptos_framework::aptos_coin;
-        use aptos_framework::transaction_fee;
         use aptos_framework::staking_config;
 
         // TODO: set because of timeout (property proved)
         pragma verify = true;
         pragma verify_duration_estimate = 600;
-        requires exists(@aptos_framework);
 
         let success = !(chain_status::is_genesis() || timestamp::spec_now_microseconds() == 0 || !reconfiguration_enabled())
             && timestamp::spec_now_microseconds() != global(@aptos_framework).last_reconfiguration_time;
         include features::spec_periodical_reward_rate_decrease_enabled() ==> staking_config::StakingRewardsConfigEnabledRequirement;
         include success ==> aptos_coin::ExistsAptosCoin;
-        include transaction_fee::RequiresCollectedFeesPerValueLeqBlockAptosSupply;
         aborts_if false;
         // The ensure conditions of the reconfigure function are not fully written, because there is a new cycle in it,
         // but its existing ensure conditions satisfy hp.
diff --git a/aptos-move/framework/aptos-framework/sources/reconfiguration_with_dkg.spec.move b/aptos-move/framework/aptos-framework/sources/reconfiguration_with_dkg.spec.move
index cddde359d5a9f..6621ee8ad2872 100644
--- a/aptos-move/framework/aptos-framework/sources/reconfiguration_with_dkg.spec.move
+++ b/aptos-move/framework/aptos-framework/sources/reconfiguration_with_dkg.spec.move
@@ -28,10 +28,8 @@ spec aptos_framework::reconfiguration_with_dkg {
         use aptos_framework::chain_status;
         use std::signer;
         use std::features;
-        use aptos_framework::stake;
         use aptos_framework::coin::CoinInfo;
         use aptos_framework::aptos_coin::AptosCoin;
-        use aptos_framework::transaction_fee;
         use aptos_framework::staking_config;
         use aptos_framework::config_buffer;
         use aptos_framework::version;
@@ -46,8 +44,6 @@ spec aptos_framework::reconfiguration_with_dkg {
         requires chain_status::is_operating();
         requires exists>(@aptos_framework);
         include staking_config::StakingRewardsConfigRequirement;
-        requires exists(@aptos_framework);
-        include transaction_fee::RequiresCollectedFeesPerValueLeqBlockAptosSupply;
         requires exists(@std);
         include config_buffer::OnNewEpochRequirement;
         include config_buffer::OnNewEpochRequirement;
diff --git a/aptos-move/framework/aptos-framework/sources/stake.move b/aptos-move/framework/aptos-framework/sources/stake.move
index 0b65fa5f4eb7d..ce3931842d776 100644
--- a/aptos-move/framework/aptos-framework/sources/stake.move
+++ b/aptos-move/framework/aptos-framework/sources/stake.move
@@ -25,7 +25,7 @@ module aptos_framework::stake {
     use std::vector;
     use aptos_std::bls12381;
     use aptos_std::math64::min;
-    use aptos_std::table::{Self, Table};
+    use aptos_std::table::Table;
     use aptos_framework::aptos_coin::AptosCoin;
     use aptos_framework::account;
     use aptos_framework::coin::{Self, Coin, MintCapability};
@@ -338,34 +338,12 @@ module aptos_framework::stake {
         pool_address: address,
     }
 
-    /// Stores transaction fees assigned to validators. All fees are distributed to validators
-    /// at the end of the epoch.
+    #[deprecated]
+    /// DEPRECATED
     struct ValidatorFees has key {
         fees_table: Table>,
     }
 
-    /// Initializes the resource storing information about collected transaction fees per validator.
-    /// Used by `transaction_fee.move` to initialize fee collection and distribution.
-    public(friend) fun initialize_validator_fees(aptos_framework: &signer) {
-        system_addresses::assert_aptos_framework(aptos_framework);
-        assert!(
-            !exists(@aptos_framework),
-            error::already_exists(EFEES_TABLE_ALREADY_EXISTS)
-        );
-        move_to(aptos_framework, ValidatorFees { fees_table: table::new() });
-    }
-
-    /// Stores the transaction fee collected to the specified validator address.
-    public(friend) fun add_transaction_fee(validator_addr: address, fee: Coin) acquires ValidatorFees {
-        let fees_table = &mut borrow_global_mut(@aptos_framework).fees_table;
-        if (table::contains(fees_table, validator_addr)) {
-            let collected_fee = table::borrow_mut(fees_table, validator_addr);
-            coin::merge(collected_fee, fee);
-        } else {
-            table::add(fees_table, validator_addr, fee);
-        }
-    }
-
     #[view]
     /// Return the lockup expiration of the stake pool at `pool_address`.
     /// This will throw an error if there's no stake pool at `pool_address`.
@@ -1232,7 +1210,7 @@ module aptos_framework::stake {
     /// 4. The validator's voting power in the validator set is updated to be the corresponding staking pool's voting
     /// power.
     public(friend) fun on_new_epoch(
-    ) acquires StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         let validator_set = borrow_global_mut(@aptos_framework);
         let config = staking_config::get();
         let validator_perf = borrow_global_mut(@aptos_framework);
@@ -1354,7 +1332,7 @@ module aptos_framework::stake {
     }
 
 
-    public fun next_validator_consensus_infos(): vector acquires ValidatorSet, ValidatorPerformance, StakePool, ValidatorFees, ValidatorConfig {
+    public fun next_validator_consensus_infos(): vector acquires ValidatorSet, ValidatorPerformance, StakePool, ValidatorConfig {
         // Init.
         let cur_validator_set = borrow_global(@aptos_framework);
         let staking_config = staking_config::get();
@@ -1409,25 +1387,16 @@ module aptos_framework::stake {
                 0
             };
 
-            let cur_fee = 0;
-            if (features::collect_and_distribute_gas_fees()) {
-                let fees_table = &borrow_global(@aptos_framework).fees_table;
-                if (table::contains(fees_table, candidate.addr)) {
-                    let fee_coin = table::borrow(fees_table, candidate.addr);
-                    cur_fee = coin::value(fee_coin);
-                }
-            };
-
             let lockup_expired = get_reconfig_start_time_secs() >= stake_pool.locked_until_secs;
             spec {
-                assume cur_active + cur_pending_active + cur_reward + cur_fee <= MAX_U64;
-                assume cur_active + cur_pending_inactive + cur_pending_active + cur_reward + cur_fee <= MAX_U64;
+                assume cur_active + cur_pending_active + cur_reward <= MAX_U64;
+                assume cur_active + cur_pending_inactive + cur_pending_active + cur_reward <= MAX_U64;
             };
             let new_voting_power =
                 cur_active
                 + if (lockup_expired) { 0 } else { cur_pending_inactive }
                 + cur_pending_active
-                + cur_reward + cur_fee;
+                + cur_reward;
 
             if (new_voting_power >= minimum_stake) {
                 let config = *borrow_global(candidate.addr);
@@ -1546,7 +1515,7 @@ module aptos_framework::stake {
         validator_perf: &ValidatorPerformance,
         pool_address: address,
         staking_config: &StakingConfig,
-    ) acquires StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorFees {
+    ) acquires StakePool, AptosCoinCapabilities, ValidatorConfig {
         let stake_pool = borrow_global_mut(pool_address);
         let validator_config = borrow_global(pool_address);
         let cur_validator_perf = vector::borrow(&validator_perf.validators, validator_config.validator_index);
@@ -1579,15 +1548,6 @@ module aptos_framework::stake {
         // Pending active stake can now be active.
         coin::merge(&mut stake_pool.active, coin::extract_all(&mut stake_pool.pending_active));
 
-        // Additionally, distribute transaction fees.
-        if (features::collect_and_distribute_gas_fees()) {
-            let fees_table = &mut borrow_global_mut(@aptos_framework).fees_table;
-            if (table::contains(fees_table, pool_address)) {
-                let coin = table::remove(fees_table, pool_address);
-                coin::merge(&mut stake_pool.active, coin);
-            };
-        };
-
         // Pending inactive stake is only fully unlocked and moved into inactive if the current lockup cycle has expired
         let current_lockup_expiration = stake_pool.locked_until_secs;
         if (get_reconfig_start_time_secs() >= current_lockup_expiration) {
@@ -1800,7 +1760,7 @@ module aptos_framework::stake {
         operator: &signer,
         pool_address: address,
         should_end_epoch: bool,
-    ) acquires AptosCoinCapabilities, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AptosCoinCapabilities, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         let pk_bytes = bls12381::public_key_to_bytes(pk);
         let pop_bytes = bls12381::proof_of_possession_to_bytes(pop);
         rotate_consensus_key(operator, pool_address, pk_bytes, pop_bytes);
@@ -1812,7 +1772,7 @@ module aptos_framework::stake {
 
     #[test_only]
     public fun fast_forward_to_unlock(pool_address: address)
-    acquires AptosCoinCapabilities, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    acquires AptosCoinCapabilities, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         let expiration_time = get_lockup_secs(pool_address);
         timestamp::update_global_time_for_test_secs(expiration_time);
         end_epoch();
@@ -1881,7 +1841,7 @@ module aptos_framework::stake {
         amount: u64,
         should_join_validator_set: bool,
         should_end_epoch: bool,
-    ) acquires AllowedValidators, AptosCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, AptosCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         let validator_address = signer::address_of(validator);
         if (!account::exists_at(signer::address_of(validator))) {
             account::create_account_for_test(validator_address);
@@ -1977,7 +1937,7 @@ module aptos_framework::stake {
     public entry fun test_inactive_validator_can_add_stake_if_exceeding_max_allowed(
         aptos_framework: &signer,
         validator: &signer,
-    ) acquires AllowedValidators, AptosCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, AptosCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         initialize_for_test(aptos_framework);
         let (_sk, pk, pop) = generate_identity();
         initialize_test_validator(&pk, &pop, validator, 100, false, false);
@@ -1992,7 +1952,7 @@ module aptos_framework::stake {
         aptos_framework: &signer,
         validator_1: &signer,
         validator_2: &signer,
-    ) acquires AllowedValidators, AptosCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, AptosCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         initialize_for_test_custom(aptos_framework, 50, 10000, LOCKUP_CYCLE_SECONDS, true, 1, 10, 100000);
         // Have one validator join the set to ensure the validator set is not empty when main validator joins.
         let (_sk_1, pk_1, pop_1) = generate_identity();
@@ -2011,7 +1971,7 @@ module aptos_framework::stake {
     public entry fun test_active_validator_cannot_add_stake_if_exceeding_max_allowed(
         aptos_framework: &signer,
         validator: &signer,
-    ) acquires AllowedValidators, AptosCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, AptosCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         initialize_for_test(aptos_framework);
         // Validator joins validator set and waits for epoch end so it's in the validator set.
         let (_sk, pk, pop) = generate_identity();
@@ -2026,7 +1986,7 @@ module aptos_framework::stake {
     public entry fun test_active_validator_with_pending_inactive_stake_cannot_add_stake_if_exceeding_max_allowed(
         aptos_framework: &signer,
         validator: &signer,
-    ) acquires AllowedValidators, AptosCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, AptosCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         initialize_for_test(aptos_framework);
         // Validator joins validator set and waits for epoch end so it's in the validator set.
         let (_sk, pk, pop) = generate_identity();
@@ -2046,7 +2006,7 @@ module aptos_framework::stake {
         aptos_framework: &signer,
         validator_1: &signer,
         validator_2: &signer,
-    ) acquires AllowedValidators, AptosCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, AptosCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         initialize_for_test(aptos_framework);
         let (_sk_1, pk_1, pop_1) = generate_identity();
         let (_sk_2, pk_2, pop_2) = generate_identity();
@@ -2064,7 +2024,7 @@ module aptos_framework::stake {
     public entry fun test_end_to_end(
         aptos_framework: &signer,
         validator: &signer,
-    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         initialize_for_test(aptos_framework);
         let (_sk, pk, pop) = generate_identity();
         initialize_test_validator(&pk, &pop, validator, 100, true, true);
@@ -2121,7 +2081,7 @@ module aptos_framework::stake {
     public entry fun test_inactive_validator_with_existing_lockup_join_validator_set(
         aptos_framework: &signer,
         validator: &signer,
-    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         initialize_for_test(aptos_framework);
         let (_sk, pk, pop) = generate_identity();
         initialize_test_validator(&pk, &pop, validator, 100, false, false);
@@ -2147,7 +2107,7 @@ module aptos_framework::stake {
     public entry fun test_cannot_reduce_lockup(
         aptos_framework: &signer,
         validator: &signer,
-    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         initialize_for_test(aptos_framework);
         let (_sk, pk, pop) = generate_identity();
         initialize_test_validator(&pk, &pop, validator, 100, false, false);
@@ -2166,7 +2126,7 @@ module aptos_framework::stake {
         aptos_framework: &signer,
         validator_1: &signer,
         validator_2: &signer,
-    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         // Only 50% voting power increase is allowed in each epoch.
         initialize_for_test_custom(aptos_framework, 50, 10000, LOCKUP_CYCLE_SECONDS, true, 1, 10, 50);
         let (_sk_1, pk_1, pop_1) = generate_identity();
@@ -2188,7 +2148,7 @@ module aptos_framework::stake {
         aptos_framework: &signer,
         validator_1: &signer,
         validator_2: &signer,
-    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         initialize_for_test_custom(aptos_framework, 50, 10000, LOCKUP_CYCLE_SECONDS, true, 1, 10, 10000);
         // Need 1 validator to be in the active validator set so joining limit works.
         let (_sk_1, pk_1, pop_1) = generate_identity();
@@ -2210,7 +2170,7 @@ module aptos_framework::stake {
         aptos_framework: &signer,
         validator_1: &signer,
         validator_2: &signer,
-    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         // 100% voting power increase is allowed in each epoch.
         initialize_for_test_custom(aptos_framework, 50, 10000, LOCKUP_CYCLE_SECONDS, true, 1, 10, 100);
         // Need 1 validator to be in the active validator set so joining limit works.
@@ -2230,7 +2190,7 @@ module aptos_framework::stake {
     public entry fun test_pending_active_validator_leaves_validator_set(
         aptos_framework: &signer,
         validator: &signer,
-    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         initialize_for_test(aptos_framework);
         // Validator joins but epoch hasn't ended, so the validator is still pending_active.
         let (_sk, pk, pop) = generate_identity();
@@ -2254,7 +2214,7 @@ module aptos_framework::stake {
     public entry fun test_active_validator_cannot_add_more_stake_than_limit_in_multiple_epochs(
         aptos_framework: &signer,
         validator: &signer,
-    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         // Only 50% voting power increase is allowed in each epoch.
         initialize_for_test_custom(aptos_framework, 50, 10000, LOCKUP_CYCLE_SECONDS, true, 1, 10, 50);
         // Add initial stake and join the validator set.
@@ -2276,7 +2236,7 @@ module aptos_framework::stake {
     public entry fun test_active_validator_cannot_add_more_stake_than_limit(
         aptos_framework: &signer,
         validator: &signer,
-    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         // Only 50% voting power increase is allowed in each epoch.
         initialize_for_test_custom(aptos_framework, 50, 10000, LOCKUP_CYCLE_SECONDS, true, 1, 10, 50);
         let (_sk, pk, pop) = generate_identity();
@@ -2290,7 +2250,7 @@ module aptos_framework::stake {
     public entry fun test_active_validator_unlock_partial_stake(
         aptos_framework: &signer,
         validator: &signer,
-    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         // Reward rate = 10%.
         initialize_for_test_custom(aptos_framework, 50, 10000, LOCKUP_CYCLE_SECONDS, true, 1, 10, 100);
         let (_sk, pk, pop) = generate_identity();
@@ -2316,7 +2276,7 @@ module aptos_framework::stake {
     public entry fun test_active_validator_can_withdraw_all_stake_and_rewards_at_once(
         aptos_framework: &signer,
         validator: &signer,
-    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         initialize_for_test(aptos_framework);
         let (_sk, pk, pop) = generate_identity();
         initialize_test_validator(&pk, &pop, validator, 100, true, true);
@@ -2353,7 +2313,7 @@ module aptos_framework::stake {
     public entry fun test_active_validator_unlocking_more_than_available_stake_should_cap(
         aptos_framework: &signer,
         validator: &signer,
-    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         initialize_for_test(aptos_framework);
         let (_sk, pk, pop) = generate_identity();
         initialize_test_validator(&pk, &pop, validator, 100, false, false);
@@ -2367,7 +2327,7 @@ module aptos_framework::stake {
     public entry fun test_active_validator_withdraw_should_cap_by_inactive_stake(
         aptos_framework: &signer,
         validator: &signer,
-    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         initialize_for_test(aptos_framework);
         // Initial balance = 900 (idle) + 100 (staked) = 1000.
         let (_sk, pk, pop) = generate_identity();
@@ -2392,7 +2352,7 @@ module aptos_framework::stake {
     public entry fun test_active_validator_can_reactivate_pending_inactive_stake(
         aptos_framework: &signer,
         validator: &signer,
-    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         initialize_for_test(aptos_framework);
         let (_sk, pk, pop) = generate_identity();
         initialize_test_validator(&pk, &pop, validator, 100, true, true);
@@ -2411,7 +2371,7 @@ module aptos_framework::stake {
     public entry fun test_active_validator_reactivate_more_than_available_pending_inactive_stake_should_cap(
         aptos_framework: &signer,
         validator: &signer,
-    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         initialize_for_test(aptos_framework);
         let (_sk, pk, pop) = generate_identity();
         initialize_test_validator(&pk, &pop, validator, 100, true, true);
@@ -2428,7 +2388,7 @@ module aptos_framework::stake {
     public entry fun test_active_validator_having_insufficient_remaining_stake_after_withdrawal_gets_kicked(
         aptos_framework: &signer,
         validator: &signer,
-    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         initialize_for_test(aptos_framework);
         let (_sk, pk, pop) = generate_identity();
         initialize_test_validator(&pk, &pop, validator, 100, true, true);
@@ -2456,7 +2416,7 @@ module aptos_framework::stake {
         aptos_framework: &signer,
         validator: &signer,
         validator_2: &signer,
-    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         initialize_for_test(aptos_framework);
         let (_sk_1, pk_1, pop_1) = generate_identity();
         let (_sk_2, pk_2, pop_2) = generate_identity();
@@ -2500,7 +2460,7 @@ module aptos_framework::stake {
         aptos_framework: &signer,
         validator: &signer,
         validator_2: &signer,
-    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         initialize_for_test(aptos_framework);
         let (_sk_1, pk_1, pop_1) = generate_identity();
         let (_sk_2, pk_2, pop_2) = generate_identity();
@@ -2531,7 +2491,7 @@ module aptos_framework::stake {
         aptos_framework: &signer,
         validator_1: &signer,
         validator_2: &signer,
-    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         // Only 50% voting power increase is allowed in each epoch.
         initialize_for_test_custom(aptos_framework, 50, 10000, LOCKUP_CYCLE_SECONDS, true, 1, 10, 50);
         let (_sk_1, pk_1, pop_1) = generate_identity();
@@ -2552,7 +2512,7 @@ module aptos_framework::stake {
         validator_1: &signer,
         validator_2: &signer,
         validator_3: &signer
-    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         let validator_1_address = signer::address_of(validator_1);
         let validator_2_address = signer::address_of(validator_2);
         let validator_3_address = signer::address_of(validator_3);
@@ -2646,7 +2606,7 @@ module aptos_framework::stake {
     public entry fun test_delegated_staking_with_owner_cap(
         aptos_framework: &signer,
         validator: &signer,
-    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         initialize_for_test_custom(aptos_framework, 100, 10000, LOCKUP_CYCLE_SECONDS, true, 1, 100, 100);
         let (_sk, pk, pop) = generate_identity();
         initialize_test_validator(&pk, &pop, validator, 0, false, false);
@@ -2699,7 +2659,7 @@ module aptos_framework::stake {
     public entry fun test_validator_cannot_join_post_genesis(
         aptos_framework: &signer,
         validator: &signer,
-    ) acquires AllowedValidators, AptosCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, AptosCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         initialize_for_test_custom(aptos_framework, 100, 10000, LOCKUP_CYCLE_SECONDS, false, 1, 100, 100);
 
         // Joining the validator set should fail as post genesis validator set change is not allowed.
@@ -2712,7 +2672,7 @@ module aptos_framework::stake {
     public entry fun test_invalid_pool_address(
         aptos_framework: &signer,
         validator: &signer,
-    ) acquires AllowedValidators, AptosCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, AptosCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         initialize_for_test(aptos_framework);
         let (_sk, pk, pop) = generate_identity();
         initialize_test_validator(&pk, &pop, validator, 100, true, true);
@@ -2724,7 +2684,7 @@ module aptos_framework::stake {
     public entry fun test_validator_cannot_leave_post_genesis(
         aptos_framework: &signer,
         validator: &signer,
-    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         initialize_for_test_custom(aptos_framework, 100, 10000, LOCKUP_CYCLE_SECONDS, false, 1, 100, 100);
         let (_sk, pk, pop) = generate_identity();
         initialize_test_validator(&pk, &pop, validator, 100, false, false);
@@ -2753,7 +2713,7 @@ module aptos_framework::stake {
         validator_3: &signer,
         validator_4: &signer,
         validator_5: &signer,
-    ) acquires AllowedValidators, AptosCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, AptosCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         let v1_addr = signer::address_of(validator_1);
         let v2_addr = signer::address_of(validator_2);
         let v3_addr = signer::address_of(validator_3);
@@ -2826,7 +2786,7 @@ module aptos_framework::stake {
         validator_3: &signer,
         validator_4: &signer,
         validator_5: &signer,
-    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         let v1_addr = signer::address_of(validator_1);
         let v2_addr = signer::address_of(validator_2);
         let v3_addr = signer::address_of(validator_3);
@@ -2889,7 +2849,7 @@ module aptos_framework::stake {
         aptos_framework: &signer,
         validator_1: &signer,
         validator_2: &signer,
-    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         initialize_for_test(aptos_framework);
 
         let validator_1_address = signer::address_of(validator_1);
@@ -2937,7 +2897,7 @@ module aptos_framework::stake {
         aptos_framework: &signer,
         validator_1: &signer,
         validator_2: &signer,
-    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         initialize_for_test(aptos_framework);
 
         let genesis_time_in_secs = timestamp::now_seconds();
@@ -2993,7 +2953,7 @@ module aptos_framework::stake {
     public entry fun test_update_performance_statistics_should_not_fail_due_to_out_of_bounds(
         aptos_framework: &signer,
         validator: &signer,
-    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         initialize_for_test(aptos_framework);
 
         let validator_address = signer::address_of(validator);
@@ -3116,7 +3076,7 @@ module aptos_framework::stake {
         aptos_framework: &signer,
         validator_1: &signer,
         validator_2: &signer,
-    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         initialize_for_test(aptos_framework);
         let (_sk_1, pk_1, pop_1) = generate_identity();
         let (_sk_2, pk_2, pop_2) = generate_identity();
@@ -3133,7 +3093,7 @@ module aptos_framework::stake {
 
     #[test_only]
     public fun end_epoch(
-    ) acquires StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         // Set the number of blocks to 1, to give out rewards to non-failing validators.
         set_validator_perf_at_least_one_block();
         timestamp::fast_forward_seconds(EPOCH_DURATION);
@@ -3213,74 +3173,4 @@ module aptos_framework::stake {
         let (numerator, denominator) = staking_config::get_reward_rate(&staking_config::get());
         amount + amount * numerator / denominator
     }
-
-    #[test_only]
-    public fun get_validator_fee(validator_addr: address): u64 acquires ValidatorFees {
-        let fees_table = &borrow_global(@aptos_framework).fees_table;
-        let coin = table::borrow(fees_table, validator_addr);
-        coin::value(coin)
-    }
-
-    #[test_only]
-    public fun assert_no_fees_for_validator(validator_addr: address) acquires ValidatorFees {
-        let fees_table = &borrow_global(@aptos_framework).fees_table;
-        assert!(!table::contains(fees_table, validator_addr), 0);
-    }
-
-    #[test_only]
-    const COLLECT_AND_DISTRIBUTE_GAS_FEES: u64 = 6;
-
-    #[test(aptos_framework = @0x1, validator_1 = @0x123, validator_2 = @0x234, validator_3 = @0x345)]
-    fun test_distribute_validator_fees(
-        aptos_framework: &signer,
-        validator_1: &signer,
-        validator_2: &signer,
-        validator_3: &signer,
-    ) acquires AllowedValidators, AptosCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
-        // Make sure that fees collection and distribution is enabled.
-        features::change_feature_flags_for_testing(aptos_framework, vector[COLLECT_AND_DISTRIBUTE_GAS_FEES], vector[]);
-        assert!(features::collect_and_distribute_gas_fees(), 0);
-
-        // Initialize staking and validator fees table.
-        initialize_for_test(aptos_framework);
-        initialize_validator_fees(aptos_framework);
-
-        let validator_1_address = signer::address_of(validator_1);
-        let validator_2_address = signer::address_of(validator_2);
-        let validator_3_address = signer::address_of(validator_3);
-
-        // Validators join the set and epoch ends.
-        let (_sk_1, pk_1, pop_1) = generate_identity();
-        let (_sk_2, pk_2, pop_2) = generate_identity();
-        let (_sk_3, pk_3, pop_3) = generate_identity();
-        initialize_test_validator(&pk_1, &pop_1, validator_1, 100, true, false);
-        initialize_test_validator(&pk_2, &pop_2, validator_2, 100, true, false);
-        initialize_test_validator(&pk_3, &pop_3, validator_3, 100, true, true);
-
-        // Next, simulate fees collection during three blocks, where proposers are
-        // validators 1, 2, and 1 again.
-        add_transaction_fee(validator_1_address, mint_coins(100));
-        add_transaction_fee(validator_2_address, mint_coins(500));
-        add_transaction_fee(validator_1_address, mint_coins(200));
-
-        // Fess have to be assigned to the right validators, but not
-        // distributed yet.
-        assert!(get_validator_fee(validator_1_address) == 300, 0);
-        assert!(get_validator_fee(validator_2_address) == 500, 0);
-        assert_no_fees_for_validator(validator_3_address);
-        assert_validator_state(validator_1_address, 100, 0, 0, 0, 2);
-        assert_validator_state(validator_2_address, 100, 0, 0, 0, 1);
-        assert_validator_state(validator_3_address, 100, 0, 0, 0, 0);
-
-        end_epoch();
-
-        // Epoch ended. Validators must have recieved their rewards and, most importantly,
-        // their fees.
-        assert_no_fees_for_validator(validator_1_address);
-        assert_no_fees_for_validator(validator_2_address);
-        assert_no_fees_for_validator(validator_3_address);
-        assert_validator_state(validator_1_address, 401, 0, 0, 0, 2);
-        assert_validator_state(validator_2_address, 601, 0, 0, 0, 1);
-        assert_validator_state(validator_3_address, 101, 0, 0, 0, 0);
-    }
 }
diff --git a/aptos-move/framework/aptos-framework/sources/stake.spec.move b/aptos-move/framework/aptos-framework/sources/stake.spec.move
index 44101fbcb134c..747c8212a3fa4 100644
--- a/aptos-move/framework/aptos-framework/sources/stake.spec.move
+++ b/aptos-move/framework/aptos-framework/sources/stake.spec.move
@@ -118,13 +118,6 @@ spec aptos_framework::stake {
     // Function specifications
     // -----------------------
 
-    spec initialize_validator_fees(aptos_framework: &signer) {
-        let aptos_addr = signer::address_of(aptos_framework);
-        aborts_if !system_addresses::is_aptos_framework_address(aptos_addr);
-        aborts_if exists(aptos_addr);
-        ensures exists(aptos_addr);
-    }
-
     spec initialize_validator(
         account: &signer,
         consensus_pubkey: vector,
@@ -496,17 +489,10 @@ spec aptos_framework::stake {
         let post post_stake_pool = global(pool_address);
         let post post_active_value = post_stake_pool.active.value;
         let post post_pending_inactive_value = post_stake_pool.pending_inactive.value;
-        let fees_table = global(@aptos_framework).fees_table;
-        let post post_fees_table = global(@aptos_framework).fees_table;
         let post post_inactive_value = post_stake_pool.inactive.value;
         ensures post_stake_pool.pending_active.value == 0;
         // the amount stored in the stake pool should not changed after the update
-        ensures if (features::spec_is_enabled(features::COLLECT_AND_DISTRIBUTE_GAS_FEES) && table::spec_contains(fees_table, pool_address)) {
-            !table::spec_contains(post_fees_table, pool_address) &&
-            post_active_value == stake_pool.active.value + rewards_amount_1 + stake_pool.pending_active.value + table::spec_get(fees_table, pool_address).value
-        } else {
-            post_active_value == stake_pool.active.value + rewards_amount_1 + stake_pool.pending_active.value
-        };
+        ensures post_active_value == stake_pool.active.value + rewards_amount_1 + stake_pool.pending_active.value;
         // when current lockup cycle has expired, pending inactive should be fully unlocked and moved into inactive
         ensures if (spec_get_reconfig_start_time_secs() >= stake_pool.locked_until_secs) {
             post_pending_inactive_value == 0 &&
@@ -527,7 +513,6 @@ spec aptos_framework::stake {
         aborts_if global(pool_address).validator_index >= len(validator_perf.validators);
 
         let aptos_addr = type_info::type_of().account_address;
-        aborts_if !exists(aptos_addr);
 
         let stake_pool = global(pool_address);
 
@@ -726,20 +711,6 @@ spec aptos_framework::stake {
             active == initial_stake_amount;
     }
 
-    spec add_transaction_fee(validator_addr: address, fee: Coin) {
-        aborts_if !exists(@aptos_framework);
-        let fees_table = global(@aptos_framework).fees_table;
-        let post post_fees_table = global(@aptos_framework).fees_table;
-        let collected_fee = table::spec_get(fees_table, validator_addr);
-        let post post_collected_fee = table::spec_get(post_fees_table, validator_addr);
-        ensures if (table::spec_contains(fees_table, validator_addr)) {
-            post_collected_fee.value == collected_fee.value + fee.value
-        } else {
-            table::spec_contains(post_fees_table, validator_addr) &&
-            table::spec_get(post_fees_table, validator_addr) == fee
-        };
-    }
-
     spec update_voting_power_increase(increase_amount: u64) {
         requires !reconfiguration_state::spec_is_in_progress();
         aborts_if !exists(@aptos_framework);
@@ -920,7 +891,6 @@ spec aptos_framework::stake {
         requires exists(@aptos_framework);
         requires exists(@aptos_framework) || !features::spec_periodical_reward_rate_decrease_enabled();
         requires exists(@aptos_framework);
-        requires exists(@aptos_framework);
     }
 
     // Adding helper function in staking_config leads to an unexpected error
diff --git a/aptos-move/framework/aptos-framework/sources/staking_contract.spec.move b/aptos-move/framework/aptos-framework/sources/staking_contract.spec.move
index e18616ff623cd..e5ad85e92ae43 100644
--- a/aptos-move/framework/aptos-framework/sources/staking_contract.spec.move
+++ b/aptos-move/framework/aptos-framework/sources/staking_contract.spec.move
@@ -589,7 +589,6 @@ spec aptos_framework::staking_contract {
         requires exists(
             @aptos_framework
         ) || !std::features::spec_periodical_reward_rate_decrease_enabled();
-        requires exists(@aptos_framework);
         requires exists(@aptos_framework);
         requires exists(@aptos_framework);
     }
diff --git a/aptos-move/framework/aptos-framework/sources/transaction_fee.move b/aptos-move/framework/aptos-framework/sources/transaction_fee.move
index 55eb05c85b659..48b1ed99d6f74 100644
--- a/aptos-move/framework/aptos-framework/sources/transaction_fee.move
+++ b/aptos-move/framework/aptos-framework/sources/transaction_fee.move
@@ -1,9 +1,8 @@
 /// This module provides an interface to burn or collect and redistribute transaction fees.
 module aptos_framework::transaction_fee {
-    use aptos_framework::coin::{Self, AggregatableCoin, BurnCapability, Coin, MintCapability};
+    use aptos_framework::coin::{Self, AggregatableCoin, BurnCapability, MintCapability};
     use aptos_framework::aptos_account;
     use aptos_framework::aptos_coin::AptosCoin;
-    use aptos_framework::stake;
     use aptos_framework::fungible_asset::BurnRef;
     use aptos_framework::system_addresses;
     use std::error;
@@ -44,14 +43,6 @@ module aptos_framework::transaction_fee {
         mint_cap: MintCapability,
     }
 
-    /// Stores information about the block proposer and the amount of fees
-    /// collected when executing the block.
-    struct CollectedFeesPerBlock has key {
-        amount: AggregatableCoin,
-        proposer: Option
, - burn_percentage: u8, - } - #[event] /// Breakdown of fee charge and refund for a transaction. /// The structure is: @@ -85,128 +76,6 @@ module aptos_framework::transaction_fee { storage_fee_refund_octas: u64, } - /// Initializes the resource storing information about gas fees collection and - /// distribution. Should be called by on-chain governance. - public fun initialize_fee_collection_and_distribution(aptos_framework: &signer, burn_percentage: u8) { - system_addresses::assert_aptos_framework(aptos_framework); - assert!( - !exists(@aptos_framework), - error::already_exists(EALREADY_COLLECTING_FEES) - ); - assert!(burn_percentage <= 100, error::out_of_range(EINVALID_BURN_PERCENTAGE)); - - // Make sure stakng module is aware of transaction fees collection. - stake::initialize_validator_fees(aptos_framework); - - // Initially, no fees are collected and the block proposer is not set. - let collected_fees = CollectedFeesPerBlock { - amount: coin::initialize_aggregatable_coin(aptos_framework), - proposer: option::none(), - burn_percentage, - }; - move_to(aptos_framework, collected_fees); - } - - fun is_fees_collection_enabled(): bool { - exists(@aptos_framework) - } - - /// Sets the burn percentage for collected fees to a new value. Should be called by on-chain governance. - public fun upgrade_burn_percentage( - aptos_framework: &signer, - new_burn_percentage: u8 - ) acquires AptosCoinCapabilities, CollectedFeesPerBlock { - system_addresses::assert_aptos_framework(aptos_framework); - assert!(new_burn_percentage <= 100, error::out_of_range(EINVALID_BURN_PERCENTAGE)); - - // Prior to upgrading the burn percentage, make sure to process collected - // fees. Otherwise we would use the new (incorrect) burn_percentage when - // processing fees later! - process_collected_fees(); - - if (is_fees_collection_enabled()) { - // Upgrade has no effect unless fees are being collected. - let burn_percentage = &mut borrow_global_mut(@aptos_framework).burn_percentage; - *burn_percentage = new_burn_percentage - } - } - - /// Registers the proposer of the block for gas fees collection. This function - /// can only be called at the beginning of the block. - public(friend) fun register_proposer_for_fee_collection(proposer_addr: address) acquires CollectedFeesPerBlock { - if (is_fees_collection_enabled()) { - let collected_fees = borrow_global_mut(@aptos_framework); - let _ = option::swap_or_fill(&mut collected_fees.proposer, proposer_addr); - } - } - - /// Burns a specified fraction of the coin. - fun burn_coin_fraction(coin: &mut Coin, burn_percentage: u8) acquires AptosCoinCapabilities { - assert!(burn_percentage <= 100, error::out_of_range(EINVALID_BURN_PERCENTAGE)); - - let collected_amount = coin::value(coin); - spec { - // We assume that `burn_percentage * collected_amount` does not overflow. - assume burn_percentage * collected_amount <= MAX_U64; - }; - let amount_to_burn = (burn_percentage as u64) * collected_amount / 100; - if (amount_to_burn > 0) { - let coin_to_burn = coin::extract(coin, amount_to_burn); - coin::burn( - coin_to_burn, - &borrow_global(@aptos_framework).burn_cap, - ); - } - } - - /// Calculates the fee which should be distributed to the block proposer at the - /// end of an epoch, and records it in the system. This function can only be called - /// at the beginning of the block or during reconfiguration. - public(friend) fun process_collected_fees() acquires AptosCoinCapabilities, CollectedFeesPerBlock { - if (!is_fees_collection_enabled()) { - return - }; - let collected_fees = borrow_global_mut(@aptos_framework); - - // If there are no collected fees, only unset the proposer. See the rationale for - // setting proposer to option::none() below. - if (coin::is_aggregatable_coin_zero(&collected_fees.amount)) { - if (option::is_some(&collected_fees.proposer)) { - let _ = option::extract(&mut collected_fees.proposer); - }; - return - }; - - // Otherwise get the collected fee, and check if it can distributed later. - let coin = coin::drain_aggregatable_coin(&mut collected_fees.amount); - if (option::is_some(&collected_fees.proposer)) { - // Extract the address of proposer here and reset it to option::none(). This - // is particularly useful to avoid any undesired side-effects where coins are - // collected but never distributed or distributed to the wrong account. - // With this design, processing collected fees enforces that all fees will be burnt - // unless the proposer is specified in the block prologue. When we have a governance - // proposal that triggers reconfiguration, we distribute pending fees and burn the - // fee for the proposal. Otherwise, that fee would be leaked to the next block. - let proposer = option::extract(&mut collected_fees.proposer); - - // Since the block can be produced by the VM itself, we have to make sure we catch - // this case. - if (proposer == @vm_reserved) { - burn_coin_fraction(&mut coin, 100); - coin::destroy_zero(coin); - return - }; - - burn_coin_fraction(&mut coin, collected_fees.burn_percentage); - stake::add_transaction_fee(proposer, coin); - return - }; - - // If checks did not pass, simply burn all collected coins and return none. - burn_coin_fraction(&mut coin, 100); - coin::destroy_zero(coin) - } - /// Burn transaction fees in epilogue. public(friend) fun burn_fee(account: address, fee: u64) acquires AptosFABurnCapabilities, AptosCoinCapabilities { if (exists(@aptos_framework)) { @@ -235,17 +104,6 @@ module aptos_framework::transaction_fee { coin::force_deposit(account, refund_coin); } - /// Collect transaction fees in epilogue. - public(friend) fun collect_fee(account: address, fee: u64) acquires CollectedFeesPerBlock { - let collected_fees = borrow_global_mut(@aptos_framework); - - // Here, we are always optimistic and always collect fees. If the proposer is not set, - // or we cannot redistribute fees later for some reason (e.g. account cannot receive AptoCoin) - // we burn them all at once. This way we avoid having a check for every transaction epilogue. - let collected_amount = &mut collected_fees.amount; - coin::collect_into_aggregatable_coin(account, fee, collected_amount); - } - /// Only called during genesis. public(friend) fun store_aptos_coin_burn_cap(aptos_framework: &signer, burn_cap: BurnCapability) { system_addresses::assert_aptos_framework(aptos_framework); @@ -274,184 +132,39 @@ module aptos_framework::transaction_fee { move_to(aptos_framework, AptosCoinMintCapability { mint_cap }) } - #[deprecated] - public fun initialize_storage_refund(_: &signer) { - abort error::not_implemented(ENO_LONGER_SUPPORTED) - } - // Called by the VM after epilogue. fun emit_fee_statement(fee_statement: FeeStatement) { event::emit(fee_statement) } - #[test_only] - use aptos_framework::aggregator_factory; - #[test_only] - use aptos_framework::object; - - #[test(aptos_framework = @aptos_framework)] - fun test_initialize_fee_collection_and_distribution(aptos_framework: signer) acquires CollectedFeesPerBlock { - aggregator_factory::initialize_aggregator_factory_for_test(&aptos_framework); - initialize_fee_collection_and_distribution(&aptos_framework, 25); - - // Check struct has been published. - assert!(exists(@aptos_framework), 0); + // DEPRECATED section: - // Check that initial balance is 0 and there is no proposer set. - let collected_fees = borrow_global(@aptos_framework); - assert!(coin::is_aggregatable_coin_zero(&collected_fees.amount), 0); - assert!(option::is_none(&collected_fees.proposer), 0); - assert!(collected_fees.burn_percentage == 25, 0); + #[deprecated] + /// DEPRECATED: Stores information about the block proposer and the amount of fees + /// collected when executing the block. + struct CollectedFeesPerBlock has key { + amount: AggregatableCoin, + proposer: Option
, + burn_percentage: u8, } - #[test(aptos_framework = @aptos_framework)] - fun test_burn_fraction_calculation(aptos_framework: signer) acquires AptosCoinCapabilities { - use aptos_framework::aptos_coin; - let (burn_cap, mint_cap) = aptos_coin::initialize_for_test(&aptos_framework); - store_aptos_coin_burn_cap(&aptos_framework, burn_cap); - - let c1 = coin::mint(100, &mint_cap); - assert!(*option::borrow(&coin::supply()) == 100, 0); - - // Burning 25%. - burn_coin_fraction(&mut c1, 25); - assert!(coin::value(&c1) == 75, 0); - assert!(*option::borrow(&coin::supply()) == 75, 0); - - // Burning 0%. - burn_coin_fraction(&mut c1, 0); - assert!(coin::value(&c1) == 75, 0); - assert!(*option::borrow(&coin::supply()) == 75, 0); - - // Burning remaining 100%. - burn_coin_fraction(&mut c1, 100); - assert!(coin::value(&c1) == 0, 0); - assert!(*option::borrow(&coin::supply()) == 0, 0); - - coin::destroy_zero(c1); - let c2 = coin::mint(10, &mint_cap); - assert!(*option::borrow(&coin::supply()) == 10, 0); - - burn_coin_fraction(&mut c2, 5); - assert!(coin::value(&c2) == 10, 0); - assert!(*option::borrow(&coin::supply()) == 10, 0); - - burn_coin_fraction(&mut c2, 100); - coin::destroy_zero(c2); - coin::destroy_burn_cap(burn_cap); - coin::destroy_mint_cap(mint_cap); + #[deprecated] + /// DEPRECATED + public fun initialize_fee_collection_and_distribution(_aptos_framework: &signer, _burn_percentage: u8) { + abort error::not_implemented(ENO_LONGER_SUPPORTED) } - #[test(aptos_framework = @aptos_framework, alice = @0xa11ce, bob = @0xb0b, carol = @0xca101)] - fun test_fees_distribution( - aptos_framework: signer, - alice: signer, - bob: signer, - carol: signer, - ) acquires AptosCoinCapabilities, CollectedFeesPerBlock { - use std::signer; - use aptos_framework::aptos_account; - use aptos_framework::aptos_coin; - - // Initialization. - let (burn_cap, mint_cap) = aptos_coin::initialize_for_test(&aptos_framework); - store_aptos_coin_burn_cap(&aptos_framework, burn_cap); - initialize_fee_collection_and_distribution(&aptos_framework, 10); - - // Create dummy accounts. - let alice_addr = signer::address_of(&alice); - let bob_addr = signer::address_of(&bob); - let carol_addr = signer::address_of(&carol); - aptos_account::create_account(alice_addr); - aptos_account::create_account(bob_addr); - aptos_account::create_account(carol_addr); - assert!(object::object_address(&coin::ensure_paired_metadata()) == @aptos_fungible_asset, 0); - coin::deposit(alice_addr, coin::mint(10000, &mint_cap)); - coin::deposit(bob_addr, coin::mint(10000, &mint_cap)); - coin::deposit(carol_addr, coin::mint(10000, &mint_cap)); - assert!(*option::borrow(&coin::supply()) == 30000, 0); - - // Block 1 starts. - process_collected_fees(); - register_proposer_for_fee_collection(alice_addr); - - // Check that there was no fees distribution in the first block. - let collected_fees = borrow_global(@aptos_framework); - assert!(coin::is_aggregatable_coin_zero(&collected_fees.amount), 0); - assert!(*option::borrow(&collected_fees.proposer) == alice_addr, 0); - assert!(*option::borrow(&coin::supply()) == 30000, 0); - - // Simulate transaction fee collection - here we simply collect some fees from Bob. - collect_fee(bob_addr, 100); - collect_fee(bob_addr, 500); - collect_fee(bob_addr, 400); - - // Now Bob must have 1000 less in his account. Alice and Carol have the same amounts. - assert!(coin::balance(alice_addr) == 10000, 0); - assert!(coin::balance(bob_addr) == 9000, 0); - assert!(coin::balance(carol_addr) == 10000, 0); - - // Block 2 starts. - process_collected_fees(); - register_proposer_for_fee_collection(bob_addr); - - // Collected fees from Bob must have been assigned to Alice. - assert!(stake::get_validator_fee(alice_addr) == 900, 0); - assert!(coin::balance(alice_addr) == 10000, 0); - assert!(coin::balance(bob_addr) == 9000, 0); - assert!(coin::balance(carol_addr) == 10000, 0); - - // Also, aggregator coin is drained and total supply is slightly changed (10% of 1000 is burnt). - let collected_fees = borrow_global(@aptos_framework); - assert!(coin::is_aggregatable_coin_zero(&collected_fees.amount), 0); - assert!(*option::borrow(&collected_fees.proposer) == bob_addr, 0); - assert!(*option::borrow(&coin::supply()) == 29900, 0); - - // Simulate transaction fee collection one more time. - collect_fee(bob_addr, 5000); - collect_fee(bob_addr, 4000); - - assert!(coin::balance(alice_addr) == 10000, 0); - assert!(coin::balance(bob_addr) == 0, 0); - assert!(coin::balance(carol_addr) == 10000, 0); - - // Block 3 starts. - process_collected_fees(); - register_proposer_for_fee_collection(carol_addr); - - // Collected fees should have been assigned to Bob because he was the peoposer. - assert!(stake::get_validator_fee(alice_addr) == 900, 0); - assert!(coin::balance(alice_addr) == 10000, 0); - assert!(stake::get_validator_fee(bob_addr) == 8100, 0); - assert!(coin::balance(bob_addr) == 0, 0); - assert!(coin::balance(carol_addr) == 10000, 0); - - // Again, aggregator coin is drained and total supply is changed by 10% of 9000. - let collected_fees = borrow_global(@aptos_framework); - assert!(coin::is_aggregatable_coin_zero(&collected_fees.amount), 0); - assert!(*option::borrow(&collected_fees.proposer) == carol_addr, 0); - assert!(*option::borrow(&coin::supply()) == 29000, 0); - - // Simulate transaction fee collection one last time. - collect_fee(alice_addr, 1000); - collect_fee(alice_addr, 1000); - - // Block 4 starts. - process_collected_fees(); - register_proposer_for_fee_collection(alice_addr); - - // Check that 2000 was collected from Alice. - assert!(coin::balance(alice_addr) == 8000, 0); - assert!(coin::balance(bob_addr) == 0, 0); - - // Carol must have some fees assigned now. - let collected_fees = borrow_global(@aptos_framework); - assert!(stake::get_validator_fee(carol_addr) == 1800, 0); - assert!(coin::is_aggregatable_coin_zero(&collected_fees.amount), 0); - assert!(*option::borrow(&collected_fees.proposer) == alice_addr, 0); - assert!(*option::borrow(&coin::supply()) == 28800, 0); + #[deprecated] + /// DEPRECATED + public fun upgrade_burn_percentage( + _aptos_framework: &signer, + _new_burn_percentage: u8 + ) { + abort error::not_implemented(ENO_LONGER_SUPPORTED) + } - coin::destroy_burn_cap(burn_cap); - coin::destroy_mint_cap(mint_cap); + #[deprecated] + public fun initialize_storage_refund(_: &signer) { + abort error::not_implemented(ENO_LONGER_SUPPORTED) } } diff --git a/aptos-move/framework/aptos-framework/sources/transaction_fee.spec.move b/aptos-move/framework/aptos-framework/sources/transaction_fee.spec.move index e11883f480788..7571861410c0a 100644 --- a/aptos-move/framework/aptos-framework/sources/transaction_fee.spec.move +++ b/aptos-move/framework/aptos-framework/sources/transaction_fee.spec.move @@ -67,132 +67,7 @@ spec aptos_framework::transaction_fee { invariant burn_percentage <= 100; } - spec initialize_fee_collection_and_distribution(aptos_framework: &signer, burn_percentage: u8) { - use std::signer; - use aptos_framework::stake::ValidatorFees; - use aptos_framework::aggregator_factory; - use aptos_framework::system_addresses; - - // property 2: The initialization function may only be called once. - /// [high-level-req-2] - aborts_if exists(@aptos_framework); - aborts_if burn_percentage > 100; - - let aptos_addr = signer::address_of(aptos_framework); - // property 3: Only the admin address is authorized to call the initialization function. - /// [high-level-req-3] - aborts_if !system_addresses::is_aptos_framework_address(aptos_addr); - aborts_if exists(aptos_addr); - - include system_addresses::AbortsIfNotAptosFramework { account: aptos_framework }; - include aggregator_factory::CreateAggregatorInternalAbortsIf; - aborts_if exists(aptos_addr); - - ensures exists(aptos_addr); - ensures exists(aptos_addr); - } - - spec upgrade_burn_percentage(aptos_framework: &signer, new_burn_percentage: u8) { - use std::signer; - - // Percentage validation - aborts_if new_burn_percentage > 100; - // Signer validation - let aptos_addr = signer::address_of(aptos_framework); - aborts_if !system_addresses::is_aptos_framework_address(aptos_addr); - - // property 5: Prior to upgrading the burn percentage, it must process all the fees collected up to that point. - // property 6: Ensure the presence of the resource. - // Requirements and ensures conditions of `process_collected_fees` - /// [high-level-req-5] - /// [high-level-req-6.3] - include ProcessCollectedFeesRequiresAndEnsures; - - // The effect of upgrading the burn percentage - ensures exists(@aptos_framework) ==> - global(@aptos_framework).burn_percentage == new_burn_percentage; - } - - spec register_proposer_for_fee_collection(proposer_addr: address) { - aborts_if false; - // property 6: Ensure the presence of the resource. - /// [high-level-req-6.1] - ensures is_fees_collection_enabled() ==> - option::spec_borrow(global(@aptos_framework).proposer) == proposer_addr; - } - - spec burn_coin_fraction(coin: &mut Coin, burn_percentage: u8) { - use aptos_framework::coin::CoinInfo; - use aptos_framework::aptos_coin::AptosCoin; - - requires burn_percentage <= 100; - requires exists(@aptos_framework); - requires exists>(@aptos_framework); - - let amount_to_burn = (burn_percentage * coin::value(coin)) / 100; - // include (amount_to_burn > 0) ==> coin::AbortsIfNotExistCoinInfo; - include amount_to_burn > 0 ==> coin::CoinSubAbortsIf { amount: amount_to_burn }; - ensures coin.value == old(coin).value - amount_to_burn; - } - - spec fun collectedFeesAggregator(): AggregatableCoin { - global(@aptos_framework).amount - } - - spec schema RequiresCollectedFeesPerValueLeqBlockAptosSupply { - use aptos_framework::optional_aggregator; - use aptos_framework::aggregator; - let maybe_supply = coin::get_coin_supply_opt(); - // property 6: Ensure the presence of the resource. - requires - (is_fees_collection_enabled() && option::is_some(maybe_supply)) ==> - (aggregator::spec_aggregator_get_val(global(@aptos_framework).amount.value) <= - optional_aggregator::optional_aggregator_value( - option::spec_borrow(coin::get_coin_supply_opt()) - )); - } - - spec schema ProcessCollectedFeesRequiresAndEnsures { - use aptos_framework::coin::CoinInfo; - use aptos_framework::aptos_coin::AptosCoin; - use aptos_framework::aggregator; - use aptos_std::table; - - requires exists(@aptos_framework); - requires exists(@aptos_framework); - requires exists>(@aptos_framework); - include RequiresCollectedFeesPerValueLeqBlockAptosSupply; - - aborts_if false; - - let collected_fees = global(@aptos_framework); - let post post_collected_fees = global(@aptos_framework); - let pre_amount = aggregator::spec_aggregator_get_val(collected_fees.amount.value); - let post post_amount = aggregator::spec_aggregator_get_val(post_collected_fees.amount.value); - let fees_table = global(@aptos_framework).fees_table; - let post post_fees_table = global(@aptos_framework).fees_table; - let proposer = option::spec_borrow(collected_fees.proposer); - let fee_to_add = pre_amount - pre_amount * collected_fees.burn_percentage / 100; - ensures is_fees_collection_enabled() ==> option::spec_is_none(post_collected_fees.proposer) && post_amount == 0; - ensures is_fees_collection_enabled() && aggregator::spec_read(collected_fees.amount.value) > 0 && - option::spec_is_some(collected_fees.proposer) ==> - if (proposer != @vm_reserved) { - if (table::spec_contains(fees_table, proposer)) { - table::spec_get(post_fees_table, proposer).value == table::spec_get( - fees_table, - proposer - ).value + fee_to_add - } else { - table::spec_get(post_fees_table, proposer).value == fee_to_add - } - } else { - option::spec_is_none(post_collected_fees.proposer) && post_amount == 0 - }; - } - - spec process_collected_fees() { - /// [high-level-req-6.2] - include ProcessCollectedFeesRequiresAndEnsures; + spec initialize_fee_collection_and_distribution(_aptos_framework: &signer, _burn_percentage: u8) { } /// `AptosCoinCapabilities` should be exists. @@ -264,30 +139,6 @@ spec aptos_framework::transaction_fee { ensures post_supply == supply + refund; } - spec collect_fee(account: address, fee: u64) { - use aptos_framework::aggregator; - // TODO(fa_migration) - pragma verify = false; - - let collected_fees = global(@aptos_framework).amount; - let aggr = collected_fees.value; - let coin_store = global>(account); - aborts_if !exists(@aptos_framework); - aborts_if fee > 0 && !exists>(account); - aborts_if fee > 0 && coin_store.coin.value < fee; - aborts_if fee > 0 && aggregator::spec_aggregator_get_val(aggr) - + fee > aggregator::spec_get_limit(aggr); - aborts_if fee > 0 && aggregator::spec_aggregator_get_val(aggr) - + fee > MAX_U128; - - let post post_coin_store = global>(account); - let post post_collected_fees = global(@aptos_framework).amount; - ensures post_coin_store.coin.value == coin_store.coin.value - fee; - ensures aggregator::spec_aggregator_get_val(post_collected_fees.value) == aggregator::spec_aggregator_get_val( - aggr - ) + fee; - } - /// Ensure caller is admin. /// Aborts if `AptosCoinCapabilities` already exists. spec store_aptos_coin_burn_cap(aptos_framework: &signer, burn_cap: BurnCapability) { diff --git a/aptos-move/framework/aptos-framework/sources/transaction_validation.move b/aptos-move/framework/aptos-framework/sources/transaction_validation.move index c3496215972e6..f9821da0b5486 100644 --- a/aptos-move/framework/aptos-framework/sources/transaction_validation.move +++ b/aptos-move/framework/aptos-framework/sources/transaction_validation.move @@ -462,26 +462,11 @@ module aptos_framework::transaction_validation { ); }; - let amount_to_burn = if (features::collect_and_distribute_gas_fees()) { - // TODO(gas): We might want to distinguish the refundable part of the charge and burn it or track - // it separately, so that we don't increase the total supply by refunding. - - // If transaction fees are redistributed to validators, collect them here for - // later redistribution. - transaction_fee::collect_fee(gas_payer, transaction_fee_amount); - 0 - } else { - // Otherwise, just burn the fee. - // TODO: this branch should be removed completely when transaction fee collection - // is tested and is fully proven to work well. - transaction_fee_amount - }; - - if (amount_to_burn > storage_fee_refunded) { - let burn_amount = amount_to_burn - storage_fee_refunded; + if (transaction_fee_amount > storage_fee_refunded) { + let burn_amount = transaction_fee_amount - storage_fee_refunded; transaction_fee::burn_fee(gas_payer, burn_amount); - } else if (amount_to_burn < storage_fee_refunded) { - let mint_amount = storage_fee_refunded - amount_to_burn; + } else if (transaction_fee_amount < storage_fee_refunded) { + let mint_amount = storage_fee_refunded - transaction_fee_amount; transaction_fee::mint_and_refund(gas_payer, mint_amount) }; }; diff --git a/aptos-move/framework/aptos-framework/sources/transaction_validation.spec.move b/aptos-move/framework/aptos-framework/sources/transaction_validation.spec.move index 799e71e414204..d97568e00374a 100644 --- a/aptos-move/framework/aptos-framework/sources/transaction_validation.spec.move +++ b/aptos-move/framework/aptos-framework/sources/transaction_validation.spec.move @@ -344,12 +344,11 @@ spec aptos_framework::transaction_validation { use std::option; use aptos_std::type_info; use aptos_framework::account::{Account}; - use aptos_framework::aggregator; use aptos_framework::aptos_coin::{AptosCoin}; use aptos_framework::coin; use aptos_framework::coin::{CoinStore, CoinInfo}; use aptos_framework::optional_aggregator; - use aptos_framework::transaction_fee::{AptosCoinCapabilities, AptosCoinMintCapability, CollectedFeesPerBlock}; + use aptos_framework::transaction_fee::{AptosCoinCapabilities, AptosCoinMintCapability}; account: signer; gas_payer: address; @@ -379,25 +378,9 @@ spec aptos_framework::transaction_validation { // ensures balance == pre_balance - transaction_fee_amount + storage_fee_refunded; ensures account.sequence_number == pre_account.sequence_number + 1; - - // Check fee collection. - let collect_fee_enabled = features::spec_is_enabled(features::COLLECT_AND_DISTRIBUTE_GAS_FEES); - let collected_fees = global(@aptos_framework).amount; - let aggr = collected_fees.value; - let aggr_val = aggregator::spec_aggregator_get_val(aggr); - let aggr_lim = aggregator::spec_get_limit(aggr); - - /// [high-level-req-3] - aborts_if collect_fee_enabled && !exists(@aptos_framework); - aborts_if collect_fee_enabled && transaction_fee_amount > 0 && aggr_val + transaction_fee_amount > aggr_lim; - // Check burning. // (Check the total supply aggregator when enabled.) - let amount_to_burn = if (collect_fee_enabled) { - 0 - } else { - transaction_fee_amount - storage_fee_refunded - }; + let amount_to_burn = transaction_fee_amount - storage_fee_refunded; let apt_addr = type_info::type_of().account_address; let maybe_apt_supply = global>(apt_addr).supply; let total_supply_enabled = option::spec_is_some(maybe_apt_supply); @@ -413,11 +396,7 @@ spec aptos_framework::transaction_validation { ensures total_supply_enabled ==> apt_supply_value - amount_to_burn == post_apt_supply_value; // Check minting. - let amount_to_mint = if (collect_fee_enabled) { - storage_fee_refunded - } else { - storage_fee_refunded - transaction_fee_amount - }; + let amount_to_mint = storage_fee_refunded - transaction_fee_amount; let total_supply = coin::supply; let post post_total_supply = coin::supply; diff --git a/aptos-move/framework/move-stdlib/doc/features.md b/aptos-move/framework/move-stdlib/doc/features.md index ae1cb772989c2..3919625f4ff9c 100644 --- a/aptos-move/framework/move-stdlib/doc/features.md +++ b/aptos-move/framework/move-stdlib/doc/features.md @@ -367,7 +367,7 @@ Lifetime: transient -Whether gas fees are collected and distributed to the block proposers. +Deprecated feature Lifetime: transient @@ -1116,9 +1116,11 @@ Lifetime: transient ## Function `get_collect_and_distribute_gas_fees_feature` +Deprecated feature -
public fun get_collect_and_distribute_gas_fees_feature(): u64
+
#[deprecated]
+public fun get_collect_and_distribute_gas_fees_feature(): u64
 
@@ -1140,7 +1142,8 @@ Lifetime: transient -
public fun collect_and_distribute_gas_fees(): bool
+
#[deprecated]
+public fun collect_and_distribute_gas_fees(): bool
 
@@ -1149,8 +1152,8 @@ Lifetime: transient Implementation -
public fun collect_and_distribute_gas_fees(): bool acquires Features {
-    is_enabled(COLLECT_AND_DISTRIBUTE_GAS_FEES)
+
public fun collect_and_distribute_gas_fees(): bool {
+    false
 }
 
@@ -3883,17 +3886,6 @@ Helper to check whether a feature flag is enabled. - - - -
fun spec_collect_and_distribute_gas_fees_enabled(): bool {
-   spec_is_enabled(COLLECT_AND_DISTRIBUTE_GAS_FEES)
-}
-
- - - - diff --git a/aptos-move/framework/move-stdlib/sources/configs/features.move b/aptos-move/framework/move-stdlib/sources/configs/features.move index 69e34db01c19b..2bdba4056eaae 100644 --- a/aptos-move/framework/move-stdlib/sources/configs/features.move +++ b/aptos-move/framework/move-stdlib/sources/configs/features.move @@ -85,14 +85,18 @@ module std::features { is_enabled(VM_BINARY_FORMAT_V6) } - /// Whether gas fees are collected and distributed to the block proposers. + #[deprecated] + /// Deprecated feature /// Lifetime: transient const COLLECT_AND_DISTRIBUTE_GAS_FEES: u64 = 6; + #[deprecated] + /// Deprecated feature public fun get_collect_and_distribute_gas_fees_feature(): u64 { COLLECT_AND_DISTRIBUTE_GAS_FEES } - public fun collect_and_distribute_gas_fees(): bool acquires Features { - is_enabled(COLLECT_AND_DISTRIBUTE_GAS_FEES) + #[deprecated] + public fun collect_and_distribute_gas_fees(): bool { + false } /// Whether the new `aptos_stdlib::multi_ed25519::public_key_validate_internal_v2()` native is enabled. diff --git a/aptos-move/framework/move-stdlib/sources/configs/features.spec.move b/aptos-move/framework/move-stdlib/sources/configs/features.spec.move index e8daa8950e396..9b8e0c8d4f4ef 100644 --- a/aptos-move/framework/move-stdlib/sources/configs/features.spec.move +++ b/aptos-move/framework/move-stdlib/sources/configs/features.spec.move @@ -66,10 +66,6 @@ spec std::features { spec_is_enabled(FEE_PAYER_ENABLED) } - spec fun spec_collect_and_distribute_gas_fees_enabled(): bool { - spec_is_enabled(COLLECT_AND_DISTRIBUTE_GAS_FEES) - } - spec fun spec_module_event_enabled(): bool { spec_is_enabled(MODULE_EVENT) } diff --git a/types/src/on_chain_config/aptos_features.rs b/types/src/on_chain_config/aptos_features.rs index 7c5f24edd4c36..24e964643e6ca 100644 --- a/types/src/on_chain_config/aptos_features.rs +++ b/types/src/on_chain_config/aptos_features.rs @@ -21,7 +21,7 @@ pub enum FeatureFlag { SHA_512_AND_RIPEMD_160_NATIVES = 3, APTOS_STD_CHAIN_ID_NATIVES = 4, VM_BINARY_FORMAT_V6 = 5, - COLLECT_AND_DISTRIBUTE_GAS_FEES = 6, + _DEPRECATED_COLLECT_AND_DISTRIBUTE_GAS_FEES = 6, MULTI_ED25519_PK_VALIDATE_V2_NATIVES = 7, BLAKE2B_256_NATIVE = 8, RESOURCE_GROUPS = 9,