Skip to content
This repository has been archived by the owner on Aug 30, 2022. It is now read-only.

rentbw #397

Merged
merged 49 commits into from
Dec 20, 2019
Merged

rentbw #397

merged 49 commits into from
Dec 20, 2019

Conversation

tbfleming
Copy link
Contributor

@tbfleming tbfleming commented Nov 27, 2019

Change Description

This PR creates a new optional NET and CPU rental market which displaces (over time)
the existing staking system and REX market. Under the old model, system token holders
own NET and CPU and may choose to use it themselves, delegate it to others, or make
it available for others to rent using the REX market. Under this new model, the chain
owns almost all NET and CPU resources and the only way to access these resources is
through the new rentbw action. It channels fees to the REX pool to enable token holders
to profit off the new market.

Renting resources

Users may use the rentbw action to rent resources:

void rentbw(
    name payer,         // The resource buyer
    name receiver,      // The resource receiver
    uint32_t days,      // Number of days of resource availability.
                        // Must match market configuration.
    int64_t net_frac,   // Fraction of net (100% = 10^15) managed by this market
    int64_t cpu_frac,   // Fraction of cpu (100% = 10^15) managed by this market
    asset max_payment   // The maximum amount `payer` is willing to pay. Tokens
                        // are withdrawn from `payer`'s token balance.
);

After the phase-in period, net_frac and cpu_frac will approximately represent the
fraction of total network resources. This should simplify resource planning since
the fraction will no longer depend on how much other accounts have staked or rented
from REX.

During the phase-in period, net_frac and cpu_frac represent the fraction managed
by the market at the time the action is called. Since the amount managed by the market
grows during phase-in, the percentage of total resources drops over the rental period.

Processing Expired Loans

The resources in loans that expire do not automatically get reclaimed by the system. The expired loans sit in a queue that must be processed. Anyone calling the rentbw action will help with processing this queue (limited to processing at most two expired loans at a time) so that normally the expired loans will be automatically processed in a timely manner. However, in some cases it may be necessary to manual process expired loans in the queue to make resources available to the system again and thus make rental prices cheaper. In such a scenario, any account may process up to an arbitrary number of expired loans by calling the rentbwexec action.

Configuration

Operators of the blockchain can use the configrentbw to start the new resource system and tune its various parameters. It is possible to call configrentbw to change certain parameters even after the new resource system has already started. Chain operators can configure the new resource system to take over the old system immediately or they can configure it to gradually phase out the old system over a long period of time.

// Configure the `rentbw` market. The market becomes available the first time this
// action is invoked.
void configrentbw( rentbw_config& args );

struct rentbw_config_resource {
   std::optional<int64_t>        current_weight_ratio;   // Immediately set weight_ratio to this amount. 1x = 10^15. 0.01x = 10^13.
                                                         //    Do not specify to preserve the existing setting or use the default;
                                                         //    this avoids sudden price jumps. For new chains which don't need
                                                         //    to gradually phase out staking and REX, 0.01x (10^13) is a good
                                                         //    value for both current_weight_ratio and target_weight_ratio.
   std::optional<int64_t>        target_weight_ratio;    // Linearly shrink weight_ratio to this amount. 1x = 10^15. 0.01x = 10^13.
                                                         //    Do not specify to preserve the existing setting or use the default.
   std::optional<int64_t>        assumed_stake_weight;   // Assumed stake weight for ratio calculations. Use the sum of total
                                                         //    staked and total rented by REX at the time the rentbw market
                                                         //    is first activated. Do not specify to preserve the existing
                                                         //    setting (no default exists); this avoids sudden price jumps.
                                                         //    For new chains which don't need to phase out staking and REX,
                                                         //    10^12 is probably a good value.
   std::optional<time_point_sec> target_timestamp;       // Stop automatic weight_ratio shrinkage at this time. Once this
                                                         //    time hits, weight_ratio will be target_weight_ratio. Ignored
                                                         //    if current_weight_ratio == target_weight_ratio. Do not specify
                                                         //    this to preserve the existing setting (no default exists).
   std::optional<double>         exponent;               // Exponent of resource price curve. Must be >= 1. Do not specify
                                                         //    to preserve the existing setting or use the default.
   std::optional<uint32_t>       decay_secs;             // Number of seconds for the gap between adjusted resource
                                                         //    utilization and instantaneous resource utilization to shrink
                                                         //    by 63%. Do not specify to preserve the existing setting or
                                                         //    use the default.
   std::optional<asset>          min_price;              // Fee needed to rent the entire resource market weight at the
                                                         //    minimum price. For example, this could be set to 0.005% of
                                                         //    total token supply. Do not specify to preserve the existing
                                                         //    setting or use the default.
   std::optional<asset>          max_price;              // Fee needed to rent the entire resource market weight at the
                                                         //    maximum price. For example, this could be set to 10% of total
                                                         //    token supply. Do not specify to preserve the existing
                                                         //    setting (no default exists).
};

struct rentbw_config {
   rentbw_config_resource  net;           // NET market configuration
   rentbw_config_resource  cpu;           // CPU market configuration
   std::optional<uint32_t> rent_days;     // `rentbw` `days` argument must match this. Do not specify to preserve the
                                          //    existing setting or use the default.
   std::optional<asset>    min_rent_fee;  // Rental fees below this amount are rejected. Do not specify to preserve the
                                          //    existing setting (no default exists).
};

Definitions useful to help understand the above, including defaults:

inline constexpr int64_t rentbw_frac = 1'000'000'000'000'000ll;  // 1.0 = 10^15

struct rentbw_state_resource {
   static constexpr double   default_exponent   = 2.0;                  // Exponent of 2.0 means that the price to rent a
                                                                        //    tiny amount of resources increases linearly
                                                                        //    with utilization.
   static constexpr uint32_t default_decay_secs = 1 * seconds_per_day;  // 1 day; if 100% of bandwidth resources are in a
                                                                        //    single loan, then, assuming no further renting,
                                                                        //    1 day after it expires the adjusted utilization
                                                                        //    will be at approximately 37% and after 3 days
                                                                        //    the adjusted utilization will be less than 5%.

   uint8_t        version                 = 0;
   int64_t        weight                  = 0;                  // resource market weight. calculated; varies over time.
                                                                //    1 represents the same amount of resources as 1
                                                                //    satoshi of SYS staked.
   int64_t        weight_ratio            = 0;                  // resource market weight ratio:
                                                                //    assumed_stake_weight / (assumed_stake_weight + weight).
                                                                //    calculated; varies over time. 1x = 10^15. 0.01x = 10^13.
   int64_t        assumed_stake_weight    = 0;                  // Assumed stake weight for ratio calculations.
   int64_t        initial_weight_ratio    = rentbw_frac;        // Initial weight_ratio used for linear shrinkage.
   int64_t        target_weight_ratio     = rentbw_frac / 100;  // Linearly shrink the weight_ratio to this amount.
   time_point_sec initial_timestamp       = {};                 // When weight_ratio shrinkage started
   time_point_sec target_timestamp        = {};                 // Stop automatic weight_ratio shrinkage at this time. Once this
                                                                //    time hits, weight_ratio will be target_weight_ratio.
   double         exponent                = default_exponent;   // Exponent of resource price curve.
   uint32_t       decay_secs              = default_decay_secs; // Number of seconds for the gap between adjusted resource
                                                                //    utilization and instantaneous utilization to shrink by 63%.
   asset          min_price               = {};                 // Fee needed to rent the entire resource market weight at
                                                                //    the minimum price (defaults to 0).
   asset          max_price               = {};                 // Fee needed to rent the entire resource market weight at
                                                                //    the maximum price.
   int64_t        utilization             = 0;                  // Instantaneous resource utilization. This is the current
                                                                //    amount sold. utilization <= weight.
   int64_t        adjusted_utilization    = 0;                  // Adjusted resource utilization. This is >= utilization and
                                                                //    <= weight. It grows instantly but decays exponentially.
   time_point_sec utilization_timestamp   = {};                 // When adjusted_utilization was last updated
};

struct rentbw_state {
   static constexpr uint32_t default_rent_days = 30; // 30 day resource rentals

   uint8_t                 version      = 0;
   rentbw_state_resource   net          = {};                 // NET market state
   rentbw_state_resource   cpu          = {};                 // CPU market state
   uint32_t                rent_days    = default_rent_days;  // `rentbw` `days` argument must match this.
   asset                   min_rent_fee = {};                 // Rental fees below this amount are rejected
};

Deployment Changes

  • Deployment Changes

A new account eosio.reserv must be created before starting the new resource system (i.e. before calling the configrentbw action). The eosio.reserv account should not be used as the authorizer of any actions because increasing the CPU/NET usage of that account could interfere with the proper functioning of the configrentbw and rentbw actions.

API Changes

  • API Changes

New actions: configrentbw, rentbwexec, rentbw

Documentation Additions

  • Documentation Additions

See the description above.

@tbfleming tbfleming changed the title resource31 rentbw Dec 11, 2019
@tbfleming tbfleming marked this pull request as ready for review December 11, 2019 18:07
@arhag arhag mentioned this pull request Dec 19, 2019
3 tasks
…en under the scenario of utilization <= adjusted_utilization
…hould preserve the existing value (or use default when appropriate)
…pricing model to now also include a min_price

Note: Assuming min_price is 0, this new price model can be directly 
compared to the prior one. In fact, under that condition, max_price can 
be thought of as target_price * exponent.
@arhag arhag changed the base branch from release/1.8.x to 1.8.x-rentbw December 20, 2019 17:31
@arhag arhag merged commit affe696 into 1.8.x-rentbw Dec 20, 2019
@arhag arhag deleted the resource31 branch December 20, 2019 20:32
@arhag arhag restored the resource31 branch December 20, 2019 20:32
@arhag arhag deleted the resource31 branch December 20, 2019 20:32
@Donutbrain
Copy link

Donutbrain commented Nov 19, 2020

How about adding a threshold in configrentbw that defines the threshold % of resources tied up in expired contracts at which anyone calling the rentbw action will automatically call rentbwexec ? You could set up tiered thresholds if desired. And perhaps a threshold to automatically process large expired loans (over a threshold % of resources) as well? You could require large loans to own a derivatives contract to pay for the processing resources on expiration (equivalent to a long call), effectively outsourcing the expiration processing costs to another market participant or group of participants. Basically I'm concerned about the potential for large jumps in liquidity as expirations are processed, and/or participants trying to game the order in which expirations are processed.

I'm an advocate for using private sidechains to mitigate these sorts of risks and costs, but I do think the proposed rental model will provide some needed flexibilities when scaling Dapps :)

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants