subscription

package
v4.1.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 7, 2024 License: Apache-2.0 Imports: 24 Imported by: 0

README

x/subscription

Abstract

This document specifies the subscription module of Lava Protocol.

The subscription module is responsible for managing Lava's consumer subscription.
To use Lava, consumers must purchase a subscription.
The subscription operates on a monthly basis, starting from the next block after purchase and ending one month later.
If a user purchases a subscription for more than one month, it will reset at the end of each month until its expiration, with the monthly remaining Compute Units (CUs) being reset to the plan's monthly CU allocation.

Subscriptions are subject to limitations set by the current policy, including a cap on monthly Compute Units (CUs).
These CUs reset with each new subscription month, ensuring users get a fresh allocation based on their plan.

A subscription can be renewed, manually or automatically.
Additionally, a subscription plan can be bought in advance for months ahead.

There are 2 other concepts that the subscription is connected to:

To fully understand this module, it is highly recommended to read Plans and Projects READMEs as well.

Contents

Concepts

Subscription

In order for a consumer to purchase a subscription, they first must choose a plan to use.
After choosing a plan, a consumer can perform the purchase using the buy transaction command:

lavad tx subscription buy [plan-index] [optional: consumer] [optional: duration(months)] [flags]

Once a consumer bought a subscription, a new instance of Subscription object will be saved into the state:

struct Subscription {
	Creator            string              // creator pays for the subscription
	Consumer           string              // consumer uses the subscription
	Block              uint64              // when the subscription was last recharged
	PlanIndex          string              // index (name) of plan
	PlanBlock          uint64              // when the plan was created
	DurationBought     uint64              // total requested duration in months
	DurationLeft       uint64              // remaining duration in months
	MonthExpiryTime    uint64              // expiry time of current month
	MonthCuTotal       uint64              // CU allowance during current month
	MonthCuLeft        uint64              // CU remaining during current month
	Cluster            string              // cluster key
	DurationTotal      uint64              // continuous subscription usage in months
	AutoRenewal        bool                // automatic renewal when the subscription expires
	FutureSubscription *FutureSubscription // future subscription made with buy --advance-purchase
}

struct FutureSubscription {
	Creator        string // creator pays for the future subscription. Will replace the original one once activated
	PlanIndex      string // index (name) of plan
	PlanBlock      uint64 // when the plan was created
	DurationBought uint64 // total requested duration in months
}

When a consumer buys a subscription, an admin project is automatically generated for them.
When the creator and consumer are different individuals, indicating that someone is purchasing a subscription for another user, the tokens will be taken out of the creator's account.

Subscriptions are saved in a fixation store (see FixationStore module for reference).

There could only be a single active subscription for a consumer.
When a consumer purchase a subscription, the tokens are transferred from their account immediately.
Those tokens are later on distributed among the providers that served that consumer, and the delegators that staked those providers.

Advance Month

One of the primary processes within this module involves the function advanceMonth, which is invoked upon the expiration of a timer set by the subscription. This function holds significance as it manages the logic that occurs at the conclusion of each month of a subscription.

The advanceMonth function plays a crucial role in the subscription lifecycle, performing several important tasks:

  1. CU Tracker Timer Update: It updates the CU tracker timer, ensuring accurate tracking of Compute Units (CUs) for the subscription. The CU tracker timer callback is responsible for paying the providers, and resetting the CU tracker data. For more information on the CU tracker, please refer to the Pairing module.

  2. Subscription Duration Management: The function checks the subscription's remaining duration. If there is time left, it deducts one month from the remaining duration and updates the total duration count, reflecting the passage of time. The details of the subscription, including CU allocations, are reset for the upcoming month.
    In cases where the subscription has reached its end (no more remaining months), different scenarios are addressed:

    • Activation of a future subscription: If a future subscription is queued, it becomes active, renewing the service.
    • Auto-renewal: If auto-renewal is enabled, an attempt is made to renew the subscription for another month. If this fails, the expired subscription is removed.
    • No future subscription or auto-renewal: The expired subscription is removed from the system.
  3. Special Cases Handling: The function also handles special cases, such as the transition to a future subscription or the implementation of auto-renewal, ensuring continuous service or appropriate termination of the subscription.

Subscription Upgrade

A subscription can be upgraded to a more expensive plan. Tokens are deducted from the creator's account immediately, and the new plan becomes effective in the next epoch. More ways to upgrade are by making an Advance Purchase or enabling Auto Renewal.

Subscription Renewal

Users have the option to renew their subscription either manually or automatically. To renew manually, users can utilize the same command as demonstrated above. They simply need to adjust the 'plan-index' to match the plan of their currently active subscription. Additionally, they can set the duration, allowing the new duration to be added to the remaining duration of the active subscription.

To renew automatically, users can use the subscription auto-renewal transaction command:

lavad tx subscription auto-renewal [true/false] [optional: plan-index] [optional: consumer] [flags]

With auto renewal, users have the flexibility to renew their subscription to any plan, regardless of whether it's cheaper or more expensive than the current active plan. The necessary tokens for renewal are deducted from the user's account at the end of each month, covering the renewal for just one month at a time. If sufficient funds are not available, the subscription will expire.

To disable auto-renewal, users can simply set the auto-renewal command to false. This will stop the subscription from renewing automatically at the end of its current cycle.

Furthermore, if a user has configured a future subscription and also set auto renewal, the auto renewal will only take effect after the future subscription expires.

Advance Purchase

Users can purchase several months of subscription in advance, using the subscription buy transaction command like so:

lavad tx subscription buy --advance-purchase [plan-index] [optional: consumer] [optional: duration(months)] [flags]

This will create the FutureSubscription object inside the Subscription object, as can be seen above. The new subscription will be triggered once the current active subscription expires.

Users can decide on the duration of this future subscription, and they'll pay the full amount for the entire period immediately. If the plan changes during that period, users who bought this plan before it changed using the --advance-purchase flag, they won't be affected by that change.

If a user tries to replace the future subscription with another, the new plan's price must be higher, considering the amount of days bought. Meaning, if user originally bought X days of a plan with price A, and now wants to advance purchase Y days of a different plan with price B, than the following must be suffice:

$$ Y * B > X * A $$

Parameters

The subscription module does not contain parameters.

Queries

The subscription module supports the following queries:

Query Arguments What it does
current consumer (string) Shows the current subscription of a consumer to a service plan
list subscription (string) Shows all current subscriptions
list-projects none Shows all the subscription's projects
next-to-month-expiry none Shows the subscriptions with the closest month expiry
tracked-cu-usage subscription (string) Shows the monthly CU usage of a specific subscription by provider
estimated-rewards provider (string), delegator/delegation_amount (optional, string/Coin) Shows the estimated monthly rewards for a specific provider. Using the optional argument, the query can return the estimated rewards of a specific delegator or the estimated rewards a delegator will get for a specific delegation amount
estimated-validator-rewards validator (string), delegator/delegation_amount (optional, string/Coin) like the estimated-rewards query, but for validators
params none Shows the parameters of the module

Note, the Coin type is from Cosmos-SDK (cosmos.base.v1beta1.Coin). From the CLI, use 100ulava to assign a Coin argument.

Also, note that the estimated-provider-rewards query might return a non-zero "recommended_block". Part of the calculated rewards are the IPRPC rewards. These IPRPC rewards estimation might be misleading in the first 24H since it's dependent on CU count, so the user should run the query again using the --height flag with the recommended_block.

Transactions

All the transactions below require setting the --from flag and gas related flags.

The subscription module supports the following transactions:

Transaction Arguments What it does Effective in
add-project project-name (string) Add a new project to a subscription next block
auto-renewal [true, false] (bool), plan-index (string, optional), consumer (optional) Enable/Disable auto-renewal to a subscription next block
buy plan-index (string), consumer (string, optional), duration (in months) (int , optional) Buy a service plan new subscription - next block;
upgrade subscription - next epoch;
advance purchase - next block;
del-project project-name (string) Delete a project from a subscription next epoch

Note that the buy transaction also support advance purchase and immediate upgrade. Refer to the help section of the commands for more details.

Proposals

The subscription module does not support any proposals.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ExportGenesis

func ExportGenesis(ctx sdk.Context, k keeper.Keeper) *types.GenesisState

ExportGenesis returns the capability module's exported genesis.

func InitGenesis

func InitGenesis(ctx sdk.Context, k keeper.Keeper, genState types.GenesisState)

InitGenesis initializes the capability module's state from a provided genesis state.

func NewHandler

func NewHandler(k keeper.Keeper) sdk.Handler

NewHandler ...

Types

type AppModule

type AppModule struct {
	AppModuleBasic
	// contains filtered or unexported fields
}

AppModule implements the AppModule interface for the capability module.

func NewAppModule

func NewAppModule(
	cdc codec.Codec,
	keeper keeper.Keeper,
	accountKeeper types.AccountKeeper,
	bankKeeper types.BankKeeper,
) AppModule

func (AppModule) BeginBlock

func (am AppModule) BeginBlock(_ sdk.Context, _ abci.RequestBeginBlock)

BeginBlock executes all ABCI BeginBlock logic respective to the capability module.

func (AppModule) ConsensusVersion

func (AppModule) ConsensusVersion() uint64

ConsensusVersion implements ConsensusVersion.

func (AppModule) EndBlock

EndBlock executes all ABCI EndBlock logic respective to the capability module. It returns no validator updates.

func (AppModule) ExportGenesis

func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage

ExportGenesis returns the capability module's exported genesis state as raw JSON bytes.

func (AppModule) GenerateGenesisState

func (AppModule) GenerateGenesisState(simState *module.SimulationState)

GenerateGenesisState creates a randomized GenState of the module

func (AppModule) InitGenesis

func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, gs json.RawMessage) []abci.ValidatorUpdate

InitGenesis performs the capability module's genesis initialization It returns no validator updates.

func (AppModule) Name

func (am AppModule) Name() string

Name returns the capability module's name.

func (AppModule) ProposalContents

ProposalContents doesn't return any content functions for governance proposals

func (AppModule) RegisterInvariants

func (am AppModule) RegisterInvariants(_ sdk.InvariantRegistry)

RegisterInvariants registers the capability module's invariants.

func (AppModule) RegisterServices

func (am AppModule) RegisterServices(cfg module.Configurator)

RegisterServices registers a GRPC query service to respond to the module-specific GRPC queries.

func (AppModule) RegisterStoreDecoder

func (am AppModule) RegisterStoreDecoder(_ sdk.StoreDecoderRegistry)

RegisterStoreDecoder registers a decoder

func (AppModule) WeightedOperations

func (am AppModule) WeightedOperations(simState module.SimulationState) []simtypes.WeightedOperation

WeightedOperations returns the all the gov module operations with their respective weights.

type AppModuleBasic

type AppModuleBasic struct {
	// contains filtered or unexported fields
}

AppModuleBasic implements the AppModuleBasic interface for the capability module.

func NewAppModuleBasic

func NewAppModuleBasic(cdc codec.BinaryCodec) AppModuleBasic

func (AppModuleBasic) DefaultGenesis

func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage

DefaultGenesis returns the capability module's default genesis state.

func (AppModuleBasic) GetQueryCmd

func (AppModuleBasic) GetQueryCmd() *cobra.Command

GetQueryCmd returns the capability module's root query command.

func (AppModuleBasic) GetTxCmd

func (a AppModuleBasic) GetTxCmd() *cobra.Command

GetTxCmd returns the capability module's root tx command.

func (AppModuleBasic) Name

func (AppModuleBasic) Name() string

Name returns the capability module's name.

func (AppModuleBasic) RegisterCodec

func (AppModuleBasic) RegisterCodec(cdc *codec.LegacyAmino)

func (AppModuleBasic) RegisterGRPCGatewayRoutes

func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux)

RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the module.

func (AppModuleBasic) RegisterInterfaces

func (a AppModuleBasic) RegisterInterfaces(reg cdctypes.InterfaceRegistry)

RegisterInterfaces registers the module's interface types

func (AppModuleBasic) RegisterLegacyAminoCodec

func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino)

func (AppModuleBasic) RegisterRESTRoutes

func (AppModuleBasic) RegisterRESTRoutes(clientCtx client.Context, rtr *mux.Router)

RegisterRESTRoutes registers the capability module's REST service handlers.

func (AppModuleBasic) ValidateGenesis

func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncodingConfig, bz json.RawMessage) error

ValidateGenesis performs genesis state validation for the capability module.

Directories

Path Synopsis
client
cli
migrations
v2
v5
v6
v7
v8
Package types is a reverse proxy.
Package types is a reverse proxy.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL