Skip to content
Snippets Groups Projects
Commit 9a5c3714 authored by inertia's avatar inertia
Browse files

#50 migrate RC wiki articles

parent 947c58d5
No related branches found
No related tags found
2 merge requests!101Deploy to Production,!100Rc system
......@@ -86,4 +86,4 @@ Additional info can also be found in [this article by hive user @holger80](https
## Allocation of RC to blockchain resources
An in depth look at how RC's are assigned to each of the three resources (CPU megacycles/state memory/history size) can be found in Hive's wiki articles for [RC Bandwidth System](https://github.com/steemit/steem/wiki/RC-Bandwidth-System) and [Parameters](https://github.com/steemit/steem/wiki/RC-Bandwidth-Parameters)
An in depth look at how RC's are assigned to each of the three resources (CPU megacycles/state memory/history size) can be found in Hive's wiki articles for [RC Bandwidth System]({{ '/tutorials-recipes/rc-bandwidth-system' | relative_url }}) and [Parameters]({{ '/tutorials-recipes/rc-bandwidth-parameters' | relative_url }}).
---
title: RC Bandwidth Parameters
position: 1
description: Analyze the dynamics of the resource budget pool.
exclude: true
layout: full
canonical_url: rc-bandwidth-parameters.html
---
### Parameters
Each pool has its own values of the following constants:
- `budget_time` : Time interval for budgeting.
- `budget` : How much the resource increases linearly over `budget_time`.
- `half_life` : Time until the resource would decay to 50% of its initial size with no load or budget.
- `drain_time` : Time until user RC would decrease to 0% of its capacity in the hypothetical world where all users have saved maximum RC, use all RC and RC regen on this resource, and the resource pool is empty (so the price is at its maximum value and there is budget but no drain).
- `inelasticity_threshold` : Percentage of the equilibrium value that serves as a boundary between elastic and inelastic prices.
### Computed values
Let us analyze the dynamics of the resource budget pool as outlined [here]({{ '/tutorials-recipes/rc-bandwidth-system' | relative_url }}) with an eye to establishing values of the parameters.
### Setting p_0
Let `p(x)` be the RC cost curve, `p(x) = A / (B + x)`.
Let's denote as `p_0` the value of `p(0)`, which is of course `p_0 = A / B`. In other words,`p_0` is the price when there are no resources in the pool. Let's set up a worst-case scenario:
- Suppose there are no resources in the pool
- Suppose all users have maximum RC reserves
- Suppose all users spend all RC reserves and regen on this resource
- Suppose all users run out of resources at time `t_drain`
Then we can solve for `p_0` in terms of `t_drain` and the budget:
```
global_rc_capacity + global_rc_regen * drain_time = p_0 * budget * drain_time
p_0 = (global_rc_capacity + global_rc_regen * drain_time) / (budget * drain_time)
```
Suppose `drain_time = 1 hour`. Then the interpretation of this equation is that, in an hour, users in the aggregate can only muster RC equal to their RC capacity plus an hour's worth of RC regen, call this much RC `rc_1h`. If we say this RC "should" be *just enough* to pay for `res_1h`, 1 hour's worth of a single resource (say, an hour's worth of history bytes). That implies a resource price of `rc_1h / res_1h`, which is the price we set the value of `p_0` to.
If we substitute for `global_rc_capacity` and simplify, we get an alternative expression for `p_0` which may be useful for some analysis:
```
p_0 = (global_rc_capacity + global_rc_regen * drain_time) / (budget * drain_time)
= (global_rc_regen * rc_regen_time + global_rc_regen * drain_time) / (budget * drain_time)
= (global_rc_regen / budget) * (1 + rc_regen_time / drain_time)
```
The first multiplicative term, `global_rc_regen / budget`, is the *balanced budget price* which would cause spending to match outflow; let us say `p_bb = global_rc_regen / budget`. This is the equilibrium price if users have no reserves and spend all RC's on this resource. This is multiplied by a multiplier which represents the temporary level the price can rise to, which is ultimately unsustainable due to finite reserves.
### Setting B
What about the constant `B`? When `x` is much smaller than `B`:
- The value of `p(x)` is approximately `A / B`
- Price `p(x)` is (almost) *inelastic* with respect to pool size `x`
- A small percentage change in `x` doesn't change `p(x)` much)
When `x` is much larger than `B` the opposite is true:
- The value of `p(x)` is approximately `A / x`
- Price `p(x)` is (almost) *elastic* with respect to pool size `x`
- A small percentage change in `x` causes an almost equal in magnitude percentage change in `p(x)`)
So while `p(x)` is never fully elastic or inelastic, you may think of `B` as being near the "midpoint" of the "transition" from almost perfectly inelastic (for small `x`) to almost perfectly elastic (for large `x`). This makes sense, since a perfectly elastic price is desirable (when possible) but unstable when the pool goes to zero (a halving of the pool results in the doubling of the price, meaning the price "doubles infinite times" as the pool goes toward zero, "halving infinite times").
Where should this transition occur? The simple answer is a small fraction of the pool's equilibrium size at no load, say `1%`, or perhaps `1/128`.
#### Inelasticity proof
A more rigorous way to say that `p(x)` is (almost) inelastic is that, for any small value `∊`, there exists some `x` small enough such that, for any small value `δ`, we have `f(x) / f((1+δ)*x) < 1+δ*∊`. (This can be interpreted as saying the percentage change in `f(x)` in response to a percentage change in `x` dies out as `x →0⁺`.)
To prove this, set `x = B*∊`. Then:
```
f(x) / f((1+δ)*x) = (A / (B+x)) / (A / (B+(1+δ)*x))
= (B+x+δ*x) / (B+x)
= 1 + δ*x / (B+x)
< 1 + δ*x / B
= 1 + δ*∊
```
#### Elasticity proof
TODO: State/prove similar condition for elasticity case.
### Decay rate
Let `τ` be the [time constant](https://en.wikipedia.org/wiki/Time_constant) for the decay rate. (The decay constant is [proportional to](https://en.wikipedia.org/wiki/Time_constant#Exponential_decay) the half-life.) The value of `τ` is essentially how much time it takes for the system to "forget" about past non-usage, and places a "soft limit" on the possibility of a very long burst of very high activity being allowed as a result of "saving up" months or years worth of inactivity. The value of `τ` is per-resource, and we've determined that resources should have short-term and long-term versions with different `τ` values. For short-term `τ` value, I recommend 1 hour. For the long-term `τ` value, I recommend 15 days.
If `Δt` time passes, then the exponential decay step of updating the pool should be `pool -= Δt * pool / τ`.
The no-load equilibrium pool size then occurs when `Δt * pool_eq / τ = Δt * budget_per_sec`, or `pool_eq = τ * budget_per_sec`.
### Discount term
Above, we set implicitly the largest (zero-stockpile) price `p_0` based on `drain_time`. It may also be useful to set the smallest possible price `p_eq` to something other than the value implied by the above equations. To do this, we can simply shift the curve downward by a factor of `D`, and scale the curve up so `p(0) = p_0`.
To elaborate:
First, define `p(x)` with discount term `D` such that
```
p(x) = (A / (B + x)) - D
```
Then set `B = inelasticity_threshold * pool_eq`. For `A` and `D` we have two equations in two unknowns:
```
p_0 = (A / B) - D
p_eq = (A / (B + pool_eq)) - D
```
Solve both equations for `A`, set the two expressions equal to each other, and solve for `D`:
```
A = B*(p_0 + D) = (p_eq+D)*(B+pool_eq)
-> B*p_0 + B*D = B*p_eq + B*D + p_eq*pool_eq + D*pool_eq
-> B*(p_0 - p_eq) - p_eq*pool_eq = D*pool_eq
-> (B / pool_eq)*(p_0 - p_eq) - p_eq = D
```
---
title: RC Bandwidth System
position: 1
description: All about the RC bandwidth system, the complete rewrite of the bandwidth system.
exclude: true
layout: full
canonical_url: rc-bandwidth-system.html
---
See also [RC Bandwidth Parameters]({{ '/tutorials-recipes/rc-bandwidth-parameters' | relative_url }})
### Introduction
The *RC bandwidth system* is a complete rewrite of the bandwidth system. Its goals include:
- Enable simple, effective UI feedback to users about bandwidth usage and remaining bandwidth
- Simplify the mental model of what buying additional SP gives users
- Reduce or eliminate unstable feedback in current bandwidth system
### History
HF20: Initial implementation.
### Resource credits
Each account has a manabar called "resource credits." Resource credits have the following characteristics:
- RC's are attached to a particular account and cannot be transferred
- An account's maximum RC is proportional to its VESTS
- Transacting uses RC
- Transactions which would cause a negative RC balance are blocked
- RC regenerates over time
### Resources
How many RC's are required for a transaction? Statelessly compute, for each transaction, how many of each *resource* it takes. Resources include:
- CPU (mega)cycles
- State memory
- History size
Then each resource has an exchange rate. If CPU cycles cost 5 RC / megacycle, state memory costs 8 RC / byte, and history size costs 4 RC / byte, a transaction which takes 2 megacycles, creates 50 bytes of state, and has a 150 byte transaction size will cost `2*5 + 50*8 + 150*4 = 1010 RC`.
### Resource budget pools
A *resource budget pool* for each resource type will be established. The resource budget pool will have a per-block linear increase, a per-block percentage decrease, and a per-transaction decrease.
For example:
- Suppose the per-block resource budget is 2500 megacycles, 5000 state bytes, and 25,000 history bytes.
- Suppose the per-block percentage decrease is 0.02%
- Suppose the pool currently contains 12,000,000 megacycles, 20,000,000 state bytes, and 80,000,000 history bytes.
- Suppose the above transaction (consuming 2 megacycles, 50 state bytes, and 150 history bytes) is the only transaction which occurs.
We can compute the new values as follows:
```
// when transaction is processed
bp.megacycles -= 2;
bp.state_bytes -= 50;
bp.history_bytes -= 150;
// per block additive
bp.megacycles += 2500;
bp.state_bytes += 5000;
bp.history_bytes += 25000;
// per block multiplicative
// of course this would be implemented as integer arithmetic
bp.megacycles *= 0.9998;
bp.state_bytes *= 0.9998;
bp.history_bytes *= 0.9998;
```
### Resource pricing
The resource budget pool can be viewed as the blockchain's "stockpile" of each resource, which it "sells" for RC. The price of each resource is based on the current level of the stockpile. Exactly how the price
is determined isn't very important, as long as it is a decreasing, smooth curve.
The specific cost curve is:
```
p(x) = A / (B + x)
```
where `A` and `B` are parameters which may be set to different values for different resources.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment