Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Redistributing fees #4967

Merged
merged 30 commits into from
Dec 13, 2022
Merged
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
f4bafca
[framework] Added resource to hold proposer/balance info
georgemitenkov Oct 11, 2022
8e89b18
[framework] Added distribution functions
georgemitenkov Oct 11, 2022
8150979
[framework] Added functionality to set fees receiver
georgemitenkov Oct 11, 2022
20c4eea
[framework] Added e2e Move test for distribution
georgemitenkov Oct 11, 2022
9e8421f
[framework] Comment fix
georgemitenkov Oct 11, 2022
d7fd4b3
[framework] Fixed failing code publishing test
georgemitenkov Oct 11, 2022
d626aba
[framework] Improved new coin name
georgemitenkov Oct 24, 2022
27fb8ee
[framework] Added docs
georgemitenkov Oct 24, 2022
03c6175
[docs] fixed gas fees distrivution docs
georgemitenkov Nov 21, 2022
5380cb9
[framework] Refactored gas fee collection
georgemitenkov Nov 22, 2022
c17ef96
[framework] Full support for transaction fee collection
georgemitenkov Nov 22, 2022
dc1f29a
[framework] Added fees table in staking module
georgemitenkov Nov 22, 2022
b7fadee
[framework] Nits for gas fee collection
georgemitenkov Nov 29, 2022
db4269f
Merge branch 'main' into george/gas-redistribution
georgemitenkov Nov 29, 2022
33a12b9
added missing markdowns and added coin test
georgemitenkov Nov 29, 2022
fb5d89d
added stake fee distribution test and removed vm signer
georgemitenkov Nov 30, 2022
7a35ea6
fixed aggregator draining on reconfiguration
georgemitenkov Nov 30, 2022
f4921b2
Merge branch 'main' into george/gas-redistribution
georgemitenkov Nov 30, 2022
8fcd4bc
addressed most of the comments
georgemitenkov Dec 1, 2022
8bc498b
Merge branch 'main' into george/gas-redistribution
georgemitenkov Dec 6, 2022
54fafa2
[framework] Added function for burn percentage upgrade
georgemitenkov Dec 6, 2022
8161782
[framework] Moved txn fee distribution into update_stake_pool
georgemitenkov Dec 7, 2022
30b7e66
Merge branch 'main' into george/gas-redistribution
georgemitenkov Dec 7, 2022
fcb12aa
[framework] Added comments
georgemitenkov Dec 9, 2022
e1b15ad
Merge branch 'main' into george/gas-redistribution
georgemitenkov Dec 9, 2022
a9ec53f
[framework] Fixed tnx fee distribution staking test
georgemitenkov Dec 9, 2022
24983f0
[framework] Addressed comments
georgemitenkov Dec 10, 2022
b293c26
Merge branch 'main' into george/gas-redistribution
georgemitenkov Dec 10, 2022
443c3d2
Merge branch 'main' into george/gas-redistribution
georgemitenkov Dec 12, 2022
70acfcd
Made lint happy
georgemitenkov Dec 12, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -79,6 +79,16 @@ module std::features {
is_enabled(VM_BINARY_FORMAT_V6)
}

/// Whether gas fees are collected and distributed to the block proposers.
/// Lifetime: transient
const COLLECT_AND_DISTRIBUTE_GAS_FEES: u64 = 6;

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)
}

// ============================================================================================
// Feature Flag Implementation

11 changes: 11 additions & 0 deletions aptos-move/framework/aptos-framework/doc/block.md
Original file line number Diff line number Diff line change
@@ -32,12 +32,14 @@ This module defines a struct storing the metadata of the block and new block eve
<pre><code><b>use</b> <a href="account.md#0x1_account">0x1::account</a>;
<b>use</b> <a href="../../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error">0x1::error</a>;
<b>use</b> <a href="event.md#0x1_event">0x1::event</a>;
<b>use</b> <a href="../../aptos-stdlib/../move-stdlib/doc/features.md#0x1_features">0x1::features</a>;
<b>use</b> <a href="../../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option">0x1::option</a>;
<b>use</b> <a href="reconfiguration.md#0x1_reconfiguration">0x1::reconfiguration</a>;
<b>use</b> <a href="stake.md#0x1_stake">0x1::stake</a>;
<b>use</b> <a href="state_storage.md#0x1_state_storage">0x1::state_storage</a>;
<b>use</b> <a href="system_addresses.md#0x1_system_addresses">0x1::system_addresses</a>;
<b>use</b> <a href="timestamp.md#0x1_timestamp">0x1::timestamp</a>;
<b>use</b> <a href="transaction_fee.md#0x1_transaction_fee">0x1::transaction_fee</a>;
</code></pre>


@@ -392,6 +394,15 @@ The runtime always runs this before executing the transactions in a block.
};
<a href="block.md#0x1_block_emit_new_block_event">emit_new_block_event</a>(&vm, &<b>mut</b> block_metadata_ref.new_block_events, new_block_event);

<b>if</b> (<a href="../../aptos-stdlib/../move-stdlib/doc/features.md#0x1_features_collect_and_distribute_gas_fees">features::collect_and_distribute_gas_fees</a>()) {
// Assign the fees collected from the previous <a href="block.md#0x1_block">block</a> <b>to</b> the previous <a href="block.md#0x1_block">block</a> proposer.
// If for <a href="../../aptos-stdlib/doc/any.md#0x1_any">any</a> reason the fees cannot be assigned, this function burns the collected coins.
<a href="transaction_fee.md#0x1_transaction_fee_process_collected_fees">transaction_fee::process_collected_fees</a>();
// Set the proposer of this <a href="block.md#0x1_block">block</a> <b>as</b> the receiver of the fees, so that the fees for this
// <a href="block.md#0x1_block">block</a> are assigned <b>to</b> the right <a href="account.md#0x1_account">account</a>.
<a href="transaction_fee.md#0x1_transaction_fee_register_proposer_for_fee_collection">transaction_fee::register_proposer_for_fee_collection</a>(proposer);
};

// Performance scores have <b>to</b> be updated before the epoch transition <b>as</b> the transaction that triggers the
// transition is the last <a href="block.md#0x1_block">block</a> in the previous epoch.
<a href="stake.md#0x1_stake_update_performance_statistics">stake::update_performance_statistics</a>(proposer_index, failed_proposer_indices);
211 changes: 209 additions & 2 deletions aptos-move/framework/aptos-framework/doc/coin.md
Original file line number Diff line number Diff line change
@@ -7,6 +7,7 @@ This module provides the foundation for typesafe Coins.


- [Struct `Coin`](#0x1_coin_Coin)
- [Struct `AggregatableCoin`](#0x1_coin_AggregatableCoin)
- [Resource `CoinStore`](#0x1_coin_CoinStore)
- [Resource `SupplyConfig`](#0x1_coin_SupplyConfig)
- [Resource `CoinInfo`](#0x1_coin_CoinInfo)
@@ -18,6 +19,11 @@ This module provides the foundation for typesafe Coins.
- [Constants](#@Constants_0)
- [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 `coin_address`](#0x1_coin_coin_address)
- [Function `balance`](#0x1_coin_balance)
- [Function `is_coin_initialized`](#0x1_coin_is_coin_initialized)
@@ -78,6 +84,8 @@ This module provides the foundation for typesafe Coins.


<pre><code><b>use</b> <a href="account.md#0x1_account">0x1::account</a>;
<b>use</b> <a href="aggregator.md#0x1_aggregator">0x1::aggregator</a>;
<b>use</b> <a href="aggregator_factory.md#0x1_aggregator_factory">0x1::aggregator_factory</a>;
<b>use</b> <a href="../../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error">0x1::error</a>;
<b>use</b> <a href="event.md#0x1_event">0x1::event</a>;
<b>use</b> <a href="../../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option">0x1::option</a>;
@@ -117,6 +125,36 @@ Main structure representing a coin/token in an account's custody.
</dl>


</details>

<a name="0x1_coin_AggregatableCoin"></a>

## 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).


<pre><code><b>struct</b> <a href="coin.md#0x1_coin_AggregatableCoin">AggregatableCoin</a>&lt;CoinType&gt; <b>has</b> store
</code></pre>



<details>
<summary>Fields</summary>


<dl>
<dt>
<code>value: <a href="aggregator.md#0x1_aggregator_Aggregator">aggregator::Aggregator</a></code>
</dt>
<dd>
Amount of aggregatable coin this address has.
</dd>
</dl>


</details>

<a name="0x1_coin_CoinStore"></a>
@@ -389,6 +427,16 @@ Capability required to burn coins.
## Constants


<a name="0x1_coin_MAX_U64"></a>

Maximum possible aggregatable coin value.


<pre><code><b>const</b> <a href="coin.md#0x1_coin_MAX_U64">MAX_U64</a>: u128 = 18446744073709551615;
</code></pre>



<a name="0x1_coin_MAX_U128"></a>

Maximum possible coin supply.
@@ -399,6 +447,16 @@ Maximum possible coin supply.



<a name="0x1_coin_EAGGREGATABLE_COIN_VALUE_TOO_LARGE"></a>

The value of aggregatable coin used for transaction fees redistribution does not fit in u64.


<pre><code><b>const</b> <a href="coin.md#0x1_coin_EAGGREGATABLE_COIN_VALUE_TOO_LARGE">EAGGREGATABLE_COIN_VALUE_TOO_LARGE</a>: u64 = 14;
</code></pre>



<a name="0x1_coin_ECOIN_INFO_ADDRESS_MISMATCH"></a>

Address of account which is used to initialize a coin <code>CoinType</code> doesn't match the deployer of module
@@ -588,6 +646,155 @@ This should be called by on-chain governance to update the config and allow



</details>

<a name="0x1_coin_initialize_aggregatable_coin"></a>

## Function `initialize_aggregatable_coin`

Creates a new aggregatable coin with value overflowing on <code>limit</code>. Note that this function can
only be called by Aptos Framework (0x1) account for now becuase of <code>create_aggregator</code>.


<pre><code><b>public</b>(<b>friend</b>) <b>fun</b> <a href="coin.md#0x1_coin_initialize_aggregatable_coin">initialize_aggregatable_coin</a>&lt;CoinType&gt;(aptos_framework: &<a href="../../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a>): <a href="coin.md#0x1_coin_AggregatableCoin">coin::AggregatableCoin</a>&lt;CoinType&gt;
</code></pre>



<details>
<summary>Implementation</summary>


<pre><code><b>public</b>(<b>friend</b>) <b>fun</b> <a href="coin.md#0x1_coin_initialize_aggregatable_coin">initialize_aggregatable_coin</a>&lt;CoinType&gt;(aptos_framework: &<a href="../../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a>): <a href="coin.md#0x1_coin_AggregatableCoin">AggregatableCoin</a>&lt;CoinType&gt; {
<b>let</b> <a href="aggregator.md#0x1_aggregator">aggregator</a> = <a href="aggregator_factory.md#0x1_aggregator_factory_create_aggregator">aggregator_factory::create_aggregator</a>(aptos_framework, <a href="coin.md#0x1_coin_MAX_U64">MAX_U64</a>);
<a href="coin.md#0x1_coin_AggregatableCoin">AggregatableCoin</a>&lt;CoinType&gt; {
value: <a href="aggregator.md#0x1_aggregator">aggregator</a>,
}
}
</code></pre>



</details>

<a name="0x1_coin_is_aggregatable_coin_zero"></a>

## Function `is_aggregatable_coin_zero`

Returns true if the value of aggregatable coin is zero.


<pre><code><b>public</b>(<b>friend</b>) <b>fun</b> <a href="coin.md#0x1_coin_is_aggregatable_coin_zero">is_aggregatable_coin_zero</a>&lt;CoinType&gt;(<a href="coin.md#0x1_coin">coin</a>: &<a href="coin.md#0x1_coin_AggregatableCoin">coin::AggregatableCoin</a>&lt;CoinType&gt;): bool
</code></pre>



<details>
<summary>Implementation</summary>


<pre><code><b>public</b>(<b>friend</b>) <b>fun</b> <a href="coin.md#0x1_coin_is_aggregatable_coin_zero">is_aggregatable_coin_zero</a>&lt;CoinType&gt;(<a href="coin.md#0x1_coin">coin</a>: &<a href="coin.md#0x1_coin_AggregatableCoin">AggregatableCoin</a>&lt;CoinType&gt;): bool {
<b>let</b> amount = <a href="aggregator.md#0x1_aggregator_read">aggregator::read</a>(&<a href="coin.md#0x1_coin">coin</a>.value);
amount == 0
}
</code></pre>



</details>

<a name="0x1_coin_drain_aggregatable_coin"></a>

## Function `drain_aggregatable_coin`

Drains the aggregatable coin, setting it to zero and returning a standard coin.


<pre><code><b>public</b>(<b>friend</b>) <b>fun</b> <a href="coin.md#0x1_coin_drain_aggregatable_coin">drain_aggregatable_coin</a>&lt;CoinType&gt;(<a href="coin.md#0x1_coin">coin</a>: &<b>mut</b> <a href="coin.md#0x1_coin_AggregatableCoin">coin::AggregatableCoin</a>&lt;CoinType&gt;): <a href="coin.md#0x1_coin_Coin">coin::Coin</a>&lt;CoinType&gt;
</code></pre>



<details>
<summary>Implementation</summary>


<pre><code><b>public</b>(<b>friend</b>) <b>fun</b> <a href="coin.md#0x1_coin_drain_aggregatable_coin">drain_aggregatable_coin</a>&lt;CoinType&gt;(<a href="coin.md#0x1_coin">coin</a>: &<b>mut</b> <a href="coin.md#0x1_coin_AggregatableCoin">AggregatableCoin</a>&lt;CoinType&gt;): <a href="coin.md#0x1_coin_Coin">Coin</a>&lt;CoinType&gt; {
<b>let</b> amount = <a href="aggregator.md#0x1_aggregator_read">aggregator::read</a>(&<a href="coin.md#0x1_coin">coin</a>.value);
<b>assert</b>!(amount &lt;= <a href="coin.md#0x1_coin_MAX_U64">MAX_U64</a>, <a href="../../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error_out_of_range">error::out_of_range</a>(<a href="coin.md#0x1_coin_EAGGREGATABLE_COIN_VALUE_TOO_LARGE">EAGGREGATABLE_COIN_VALUE_TOO_LARGE</a>));

<a href="aggregator.md#0x1_aggregator_sub">aggregator::sub</a>(&<b>mut</b> <a href="coin.md#0x1_coin">coin</a>.value, amount);
<a href="coin.md#0x1_coin_Coin">Coin</a>&lt;CoinType&gt; {
value: (amount <b>as</b> u64),
}
}
</code></pre>



</details>

<a name="0x1_coin_merge_aggregatable_coin"></a>

## Function `merge_aggregatable_coin`

Merges <code><a href="coin.md#0x1_coin">coin</a></code> into aggregatable coin (<code>dst_coin</code>).


<pre><code><b>public</b>(<b>friend</b>) <b>fun</b> <a href="coin.md#0x1_coin_merge_aggregatable_coin">merge_aggregatable_coin</a>&lt;CoinType&gt;(dst_coin: &<b>mut</b> <a href="coin.md#0x1_coin_AggregatableCoin">coin::AggregatableCoin</a>&lt;CoinType&gt;, <a href="coin.md#0x1_coin">coin</a>: <a href="coin.md#0x1_coin_Coin">coin::Coin</a>&lt;CoinType&gt;)
</code></pre>



<details>
<summary>Implementation</summary>


<pre><code><b>public</b>(<b>friend</b>) <b>fun</b> <a href="coin.md#0x1_coin_merge_aggregatable_coin">merge_aggregatable_coin</a>&lt;CoinType&gt;(dst_coin: &<b>mut</b> <a href="coin.md#0x1_coin_AggregatableCoin">AggregatableCoin</a>&lt;CoinType&gt;, <a href="coin.md#0x1_coin">coin</a>: <a href="coin.md#0x1_coin_Coin">Coin</a>&lt;CoinType&gt;) {
<b>let</b> <a href="coin.md#0x1_coin_Coin">Coin</a> { value } = <a href="coin.md#0x1_coin">coin</a>;
<b>let</b> amount = (value <b>as</b> u128);
<a href="aggregator.md#0x1_aggregator_add">aggregator::add</a>(&<b>mut</b> dst_coin.value, amount);
}
</code></pre>



</details>

<a name="0x1_coin_collect_into_aggregatable_coin"></a>

## Function `collect_into_aggregatable_coin`

Collects a specified amount of coin form an account into aggregatable coin.


<pre><code><b>public</b>(<b>friend</b>) <b>fun</b> <a href="coin.md#0x1_coin_collect_into_aggregatable_coin">collect_into_aggregatable_coin</a>&lt;CoinType&gt;(account_addr: <b>address</b>, amount: u64, dst_coin: &<b>mut</b> <a href="coin.md#0x1_coin_AggregatableCoin">coin::AggregatableCoin</a>&lt;CoinType&gt;)
</code></pre>



<details>
<summary>Implementation</summary>


<pre><code><b>public</b>(<b>friend</b>) <b>fun</b> <a href="coin.md#0x1_coin_collect_into_aggregatable_coin">collect_into_aggregatable_coin</a>&lt;CoinType&gt;(
account_addr: <b>address</b>,
amount: u64,
dst_coin: &<b>mut</b> <a href="coin.md#0x1_coin_AggregatableCoin">AggregatableCoin</a>&lt;CoinType&gt;,
) <b>acquires</b> <a href="coin.md#0x1_coin_CoinStore">CoinStore</a> {
// Skip collecting <b>if</b> amount is zero.
<b>if</b> (amount == 0) {
<b>return</b>
};

<b>let</b> coin_store = <b>borrow_global_mut</b>&lt;<a href="coin.md#0x1_coin_CoinStore">CoinStore</a>&lt;CoinType&gt;&gt;(account_addr);
<b>let</b> <a href="coin.md#0x1_coin">coin</a> = <a href="coin.md#0x1_coin_extract">extract</a>(&<b>mut</b> coin_store.<a href="coin.md#0x1_coin">coin</a>, amount);
<a href="coin.md#0x1_coin_merge_aggregatable_coin">merge_aggregatable_coin</a>(dst_coin, <a href="coin.md#0x1_coin">coin</a>);
}
</code></pre>



</details>

<a name="0x1_coin_coin_address"></a>
@@ -1248,7 +1455,7 @@ to the sum of the two tokens (<code>dst_coin</code> and <code>source_coin</code>

<pre><code><b>public</b> <b>fun</b> <a href="coin.md#0x1_coin_merge">merge</a>&lt;CoinType&gt;(dst_coin: &<b>mut</b> <a href="coin.md#0x1_coin_Coin">Coin</a>&lt;CoinType&gt;, source_coin: <a href="coin.md#0x1_coin_Coin">Coin</a>&lt;CoinType&gt;) {
<b>spec</b> {
<b>assume</b> dst_coin.value + source_coin.<a href="coin.md#0x1_coin_value">value</a> &lt;= MAX_U64;
<b>assume</b> dst_coin.value + source_coin.<a href="coin.md#0x1_coin_value">value</a> &lt;= <a href="coin.md#0x1_coin_MAX_U64">MAX_U64</a>;
};
dst_coin.value = dst_coin.value + source_coin.value;
<b>let</b> <a href="coin.md#0x1_coin_Coin">Coin</a> { value: _ } = source_coin;
@@ -2031,7 +2238,7 @@ Updating <code>Account.guid_creation_num</code> will not overflow.
<pre><code><b>pragma</b> aborts_if_is_partial;
<b>let</b> account_addr = <a href="../../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer_address_of">signer::address_of</a>(<a href="account.md#0x1_account">account</a>);
<b>let</b> acc = <b>global</b>&lt;<a href="account.md#0x1_account_Account">account::Account</a>&gt;(account_addr);
<b>aborts_if</b> acc.guid_creation_num + 2 &gt; MAX_U64;
<b>aborts_if</b> acc.guid_creation_num + 2 &gt; <a href="coin.md#0x1_coin_MAX_U64">MAX_U64</a>;
<b>aborts_if</b> <b>exists</b>&lt;<a href="coin.md#0x1_coin_CoinStore">CoinStore</a>&lt;CoinType&gt;&gt;(account_addr);
<b>aborts_if</b> !<b>exists</b>&lt;<a href="account.md#0x1_account_Account">account::Account</a>&gt;(account_addr);
<b>ensures</b> <b>exists</b>&lt;<a href="coin.md#0x1_coin_CoinStore">CoinStore</a>&lt;CoinType&gt;&gt;(account_addr);
Loading