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

[aptos-framework] permissioned_delegation with rate limiter #15114

Merged
merged 6 commits into from
Jan 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions aptos-move/framework/aptos-framework/doc/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,14 @@ This is the reference documentation of the Aptos framework.
- [`0x1::object_code_deployment`](object_code_deployment.md#0x1_object_code_deployment)
- [`0x1::optional_aggregator`](optional_aggregator.md#0x1_optional_aggregator)
- [`0x1::ordered_map`](ordered_map.md#0x1_ordered_map)
- [`0x1::permissioned_delegation`](permissioned_delegation.md#0x1_permissioned_delegation)
- [`0x1::permissioned_signer`](permissioned_signer.md#0x1_permissioned_signer)
- [`0x1::primary_fungible_store`](primary_fungible_store.md#0x1_primary_fungible_store)
- [`0x1::randomness`](randomness.md#0x1_randomness)
- [`0x1::randomness_api_v0_config`](randomness_api_v0_config.md#0x1_randomness_api_v0_config)
- [`0x1::randomness_config`](randomness_config.md#0x1_randomness_config)
- [`0x1::randomness_config_seqnum`](randomness_config_seqnum.md#0x1_randomness_config_seqnum)
- [`0x1::rate_limiter`](rate_limiter.md#0x1_rate_limiter)
- [`0x1::reconfiguration`](reconfiguration.md#0x1_reconfiguration)
- [`0x1::reconfiguration_state`](reconfiguration_state.md#0x1_reconfiguration_state)
- [`0x1::reconfiguration_with_dkg`](reconfiguration_with_dkg.md#0x1_reconfiguration_with_dkg)
Expand Down
323 changes: 223 additions & 100 deletions aptos-move/framework/aptos-framework/doc/permissioned_delegation.md

Large diffs are not rendered by default.

180 changes: 180 additions & 0 deletions aptos-move/framework/aptos-framework/doc/rate_limiter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@

<a id="0x1_rate_limiter"></a>

# Module `0x1::rate_limiter`



- [Enum Resource `RateLimiter`](#0x1_rate_limiter_RateLimiter)
- [Function `initialize`](#0x1_rate_limiter_initialize)
- [Function `request`](#0x1_rate_limiter_request)
- [Function `refill`](#0x1_rate_limiter_refill)


<pre><code><b>use</b> <a href="timestamp.md#0x1_timestamp">0x1::timestamp</a>;
</code></pre>



<a id="0x1_rate_limiter_RateLimiter"></a>

## Enum Resource `RateLimiter`



<pre><code>enum <a href="rate_limiter.md#0x1_rate_limiter_RateLimiter">RateLimiter</a> <b>has</b> <b>copy</b>, drop, store, key
</code></pre>



<details>
<summary>Variants</summary>


<details>
<summary>TokenBucket</summary>


<details>
<summary>Fields</summary>


<dl>
<dt>
<code>capacity: u64</code>
</dt>
<dd>

</dd>
<dt>
<code>current_amount: u64</code>
</dt>
<dd>

</dd>
<dt>
<code>refill_interval: u64</code>
</dt>
<dd>

</dd>
<dt>
<code>last_refill_timestamp: u64</code>
</dt>
<dd>

</dd>
<dt>
<code>fractional_accumulated: u64</code>
</dt>
<dd>

</dd>
</dl>


</details>

</details>

</details>

<a id="0x1_rate_limiter_initialize"></a>

## Function `initialize`



<pre><code><b>public</b> <b>fun</b> <a href="rate_limiter.md#0x1_rate_limiter_initialize">initialize</a>(capacity: u64, refill_interval: u64): <a href="rate_limiter.md#0x1_rate_limiter_RateLimiter">rate_limiter::RateLimiter</a>
</code></pre>



<details>
<summary>Implementation</summary>


<pre><code><b>public</b> <b>fun</b> <a href="rate_limiter.md#0x1_rate_limiter_initialize">initialize</a>(capacity: u64, refill_interval: u64): <a href="rate_limiter.md#0x1_rate_limiter_RateLimiter">RateLimiter</a> {
RateLimiter::TokenBucket {
capacity,
current_amount: capacity, // Start <b>with</b> a full bucket (full capacity of transactions allowed)
refill_interval,
last_refill_timestamp: <a href="timestamp.md#0x1_timestamp_now_seconds">timestamp::now_seconds</a>(),
fractional_accumulated: 0, // Start <b>with</b> no fractional accumulated
}
}
</code></pre>



</details>

<a id="0x1_rate_limiter_request"></a>

## Function `request`



<pre><code><b>public</b> <b>fun</b> <a href="rate_limiter.md#0x1_rate_limiter_request">request</a>(limiter: &<b>mut</b> <a href="rate_limiter.md#0x1_rate_limiter_RateLimiter">rate_limiter::RateLimiter</a>, num_token_requested: u64): bool
</code></pre>



<details>
<summary>Implementation</summary>


<pre><code><b>public</b> <b>fun</b> <a href="rate_limiter.md#0x1_rate_limiter_request">request</a>(limiter: &<b>mut</b> <a href="rate_limiter.md#0x1_rate_limiter_RateLimiter">RateLimiter</a>, num_token_requested: u64): bool {
<a href="rate_limiter.md#0x1_rate_limiter_refill">refill</a>(limiter);
<b>if</b> (limiter.current_amount &gt;= num_token_requested) {
limiter.current_amount = limiter.current_amount - num_token_requested;
<b>true</b>
} <b>else</b> {
<b>false</b>
}
}
</code></pre>



</details>

<a id="0x1_rate_limiter_refill"></a>

## Function `refill`



<pre><code><b>fun</b> <a href="rate_limiter.md#0x1_rate_limiter_refill">refill</a>(limiter: &<b>mut</b> <a href="rate_limiter.md#0x1_rate_limiter_RateLimiter">rate_limiter::RateLimiter</a>)
</code></pre>



<details>
<summary>Implementation</summary>


<pre><code><b>fun</b> <a href="rate_limiter.md#0x1_rate_limiter_refill">refill</a>(limiter: &<b>mut</b> <a href="rate_limiter.md#0x1_rate_limiter_RateLimiter">RateLimiter</a>) {
<b>let</b> current_time = <a href="timestamp.md#0x1_timestamp_now_seconds">timestamp::now_seconds</a>();
<b>let</b> time_passed = current_time - limiter.last_refill_timestamp;
// Calculate the full tokens that can be added
<b>let</b> accumulated_amount = time_passed * limiter.capacity + limiter.fractional_accumulated;
<b>let</b> new_tokens = accumulated_amount / limiter.refill_interval;
<b>if</b> (limiter.current_amount + new_tokens &gt;= limiter.capacity) {
limiter.current_amount = limiter.capacity;
limiter.fractional_accumulated = 0;
} <b>else</b> {
limiter.current_amount = limiter.current_amount + new_tokens;
// Update the fractional amount accumulated for the next refill cycle
limiter.fractional_accumulated = accumulated_amount % limiter.refill_interval;
};
limiter.last_refill_timestamp = current_time;
}
</code></pre>



</details>


[move-book]: https://aptos.dev/move/book/SUMMARY
176 changes: 176 additions & 0 deletions aptos-move/framework/aptos-framework/doc/token_bucket.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@

<a id="0x1_token_bucket"></a>

# Module `0x1::token_bucket`



- [Resource `Bucket`](#0x1_token_bucket_Bucket)
- [Function `initialize_bucket`](#0x1_token_bucket_initialize_bucket)
- [Function `request`](#0x1_token_bucket_request)
- [Function `refill`](#0x1_token_bucket_refill)


<pre><code><b>use</b> <a href="../../aptos-stdlib/doc/math64.md#0x1_math64">0x1::math64</a>;
<b>use</b> <a href="timestamp.md#0x1_timestamp">0x1::timestamp</a>;
</code></pre>



<a id="0x1_token_bucket_Bucket"></a>

## Resource `Bucket`



<pre><code><b>struct</b> <a href="token_bucket.md#0x1_token_bucket_Bucket">Bucket</a> <b>has</b> <b>copy</b>, drop, store, key
</code></pre>



<details>
<summary>Fields</summary>


<dl>
<dt>
<code>capacity: u64</code>
</dt>
<dd>

</dd>
<dt>
<code>tokens: u64</code>
</dt>
<dd>

</dd>
<dt>
<code>refill_rate_per_minute: u64</code>
</dt>
<dd>

</dd>
<dt>
<code>last_refill_timestamp: u64</code>
</dt>
<dd>

</dd>
<dt>
<code>fractional_time_accumulated: u64</code>
</dt>
<dd>

</dd>
</dl>


</details>

<a id="0x1_token_bucket_initialize_bucket"></a>

## Function `initialize_bucket`



<pre><code><b>public</b> <b>fun</b> <a href="token_bucket.md#0x1_token_bucket_initialize_bucket">initialize_bucket</a>(capacity: u64): <a href="token_bucket.md#0x1_token_bucket_Bucket">token_bucket::Bucket</a>
</code></pre>



<details>
<summary>Implementation</summary>


<pre><code><b>public</b> <b>fun</b> <a href="token_bucket.md#0x1_token_bucket_initialize_bucket">initialize_bucket</a>(capacity: u64): <a href="token_bucket.md#0x1_token_bucket_Bucket">Bucket</a> {
<b>let</b> bucket = <a href="token_bucket.md#0x1_token_bucket_Bucket">Bucket</a> {
capacity,
tokens: capacity, // Start <b>with</b> a full bucket (full capacity of transactions allowed)
refill_rate_per_minute: capacity,
last_refill_timestamp: <a href="timestamp.md#0x1_timestamp_now_seconds">timestamp::now_seconds</a>(),
fractional_time_accumulated: 0, // Start <b>with</b> no fractional time accumulated
};
bucket
}
</code></pre>



</details>

<a id="0x1_token_bucket_request"></a>

## Function `request`



<pre><code><b>public</b> <b>fun</b> <a href="token_bucket.md#0x1_token_bucket_request">request</a>(bucket: &<b>mut</b> <a href="token_bucket.md#0x1_token_bucket_Bucket">token_bucket::Bucket</a>, num_token_requested: u64): bool
</code></pre>



<details>
<summary>Implementation</summary>


<pre><code><b>public</b> <b>fun</b> <a href="token_bucket.md#0x1_token_bucket_request">request</a>(bucket: &<b>mut</b> <a href="token_bucket.md#0x1_token_bucket_Bucket">Bucket</a>, num_token_requested: u64): bool {
<a href="token_bucket.md#0x1_token_bucket_refill">refill</a>(bucket);
<b>if</b> (bucket.tokens &gt;= num_token_requested) {
bucket.tokens = bucket.tokens - num_token_requested;
<b>true</b>
} <b>else</b> {
<b>false</b>
}
}
</code></pre>



</details>

<a id="0x1_token_bucket_refill"></a>

## Function `refill`



<pre><code><b>fun</b> <a href="token_bucket.md#0x1_token_bucket_refill">refill</a>(bucket: &<b>mut</b> <a href="token_bucket.md#0x1_token_bucket_Bucket">token_bucket::Bucket</a>)
</code></pre>



<details>
<summary>Implementation</summary>


<pre><code><b>fun</b> <a href="token_bucket.md#0x1_token_bucket_refill">refill</a>(bucket: &<b>mut</b> <a href="token_bucket.md#0x1_token_bucket_Bucket">Bucket</a>) {
<b>let</b> current_time = <a href="timestamp.md#0x1_timestamp_now_seconds">timestamp::now_seconds</a>();
<b>let</b> time_passed = current_time - bucket.last_refill_timestamp;

// Total time passed including fractional accumulated time
<b>let</b> total_time = time_passed + bucket.fractional_time_accumulated;

// Calculate the full tokens that can be added
<b>let</b> new_tokens = total_time * bucket.refill_rate_per_minute / 60;

// Calculate the remaining fractional time
<b>let</b> remaining_fractional_time = total_time % 60;

// Refill the bucket <b>with</b> the full tokens
<b>if</b> (new_tokens &gt; 0) {
bucket.tokens = <a href="../../aptos-stdlib/doc/math64.md#0x1_math64_min">math64::min</a>(bucket.tokens + new_tokens, bucket.capacity);
bucket.last_refill_timestamp = current_time;
};

// Update the fractional time accumulated for the next refill cycle
bucket.fractional_time_accumulated = remaining_fractional_time;
}
</code></pre>



</details>


[move-book]: https://aptos.dev/move/book/SUMMARY
Loading
Loading