Skip to content

Commit

Permalink
Merge branch 'main' into CNS-1009-estimated-rewards-by-cu
Browse files Browse the repository at this point in the history
  • Loading branch information
oren-lava committed Oct 10, 2024
2 parents c34e53a + 4394756 commit 1071628
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 25 deletions.
8 changes: 4 additions & 4 deletions x/dualstaking/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ Dualstaking makes this happen by "duplicating" delegations, for each validator d
### Delegation

Dualstaking introduces provider delegations to the Lava network. Provider delegations allow users to delegate their tokens to a specific provider, similar to validators, in order to contribute to their success and claim a portion of the rewards awarded to the provider.
When a provider stakes tokens, they create a self-delegation entry. Whenever a provider receives rewards, all delegators are eligible for a portion of the rewards based on their delegation amount and the commission rate set by the provider.
When a provider stakes tokens, they create a self-delegation entry. Whenever a provider receives rewards, all delegators are eligible for a portion of the rewards based on their delegation amount and the commission rate set by the provider. The delegations for a provider is split between the chains of the provider, distributed according the the providers stakes.

### Empty Provider

Expand Down Expand Up @@ -123,9 +123,9 @@ The Dualstaking module supports the following transactions:

| Transaction | Arguments | What it does |
| ---------- | --------------- | ----------------------------------------------|
| `delegate` | validator-addr(string) provider-addr (string) chain-id (string) amount (coin)| delegate to validator and provider the given amount|
| `redelegate` | src-provider-addr (string) src-chain-id (string) dst-provider-addr (string) dst-chain-id (string) amount (coin)| redelegate provider delegation from source provider to destination provider|
| `unbond` | validator-addr (string) provider-addr (string) chain-id (string) amount (coin) | undong from validator and provider the given amount |
| `delegate` | validator-addr(string) provider-addr (string) amount (coin)| delegate to validator and provider the given amount|
| `redelegate` | src-provider-addr (string) dst-provider-addr (string) amount (coin)| redelegate provider delegation from source provider to destination provider|
| `unbond` | validator-addr (string) provider-addr (string) amount (coin) | undong from validator and provider the given amount |
| `claim-rewards` | optional: provider-addr (string)| claim the rewards from a given provider or all rewards |


Expand Down
17 changes: 17 additions & 0 deletions x/epochstorage/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Note that the module will make sure that any changes will be applied only in the
* [Epoch](#epoch)
* [EpochDetails](#epochdetails)
* [FixatedParams](#fixatedparams)
* [Metadata](#metadata)
* [StakeEntry](#stakeentry)
* [StakeEntry Storage](#stakeentry-storage)
* [Parameters](#parameters)
Expand Down Expand Up @@ -63,6 +64,21 @@ type FixatedParams struct {

This is done in the [BeginBlock method of the module](keeper/fixated_params.go)

### Metadata

The metadata struct includes all the data for a provider that is the same accross all chains
```go
type ProviderMetadata struct {
Provider string // provider address
Vault string // vault address
TotalDelegations types.Coin // total delegations by delegators
Chains []string // list of all chain ids the provider is staken on
DelegateCommission uint64 // provider commission from rewards
LastChange uint64 // date of the last commission change
Description types1.Description // string descriptions of the provider entity (moniker, identity, wesite...)
}
```

### StakeEntry

The stake entry is a struct that contains all the information of a provider.
Expand Down Expand Up @@ -146,6 +162,7 @@ The epochstorage module supports the following queries:
| `show-fixated-params` | chainid | a specific fixated param |
| `list-stake-storage` | chainid | list of all stake storages indices |
| `show-stake-storage` | chainid | show a specific stake storage |
| `provider-metadata` | provider-address | shows the metadata of a specific provider, if left empty returns metadata for all providers |

## Transactions

Expand Down
11 changes: 11 additions & 0 deletions x/pairing/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,16 @@ A consumer sends requests to a provider's endpoint to communicate with them. The

Stake entries' storage is managed by the epochstorage module. For more details, see its README.

Providers `DelegateTotal` is the delegators delegations part for this chain and is calculated by as follows: `total_provider_delegations` * `stake` / `total_stake`

when:

`stake` is the providers stake on a specific chain

`total_stake` is the total stake of the provider across all chains

`total_provider_delegations` is the total delegations for the provider

#### Unstake

A provider can unstake and retrieve their coins. When a provider unstakes, they are removed from the pairing list starting from the next epoch. After a specified number of blocks called `UnstakeHoldBlocks` (a parameter of the epochstorage module), the provider is eligible to receive their coins back.
Expand Down Expand Up @@ -354,6 +364,7 @@ The pairing module supports the following transactions:
| `stake-provider` | chain-id (string), amount (Coin), endpoints ([]Endpoint), geolocation (int32), validator (string, optional), --provider-moniker (string) --grant-provider-gas-fees-auth (bool)| stake a provider in a chain with multiple endpoints |
| `unfreeze` | chain-ids ([]string) | unfreeze a provider in multiple chains |
| `unstake-provider` | chain-ids ([]string), validator (string, optional) | unstake a provider from multiple chains |
| `move-provider-stake` | src-chain dst-chain amount (Coin)| move provider stake amount from one chain to another |

Note, the `Coin` type is from Cosmos-SDK (`cosmos.base.v1beta1.Coin`). From the CLI, use `100ulava` to assign a `Coin` argument. The `Endpoint` type defines a provider endpoint. From the CLI, use "my-provider-grpc-addr.com:9090,1" for one endpoint (includes the endpoint's URL+port and the endpoint's geolocation). When it comes to staking-related transactions, the geolocation argument should encompass the geolocations of all the endpoints combined.

Expand Down
2 changes: 1 addition & 1 deletion x/pairing/keeper/delegator_rewards_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -688,7 +688,7 @@ func TestDelegatorRewardProviderAddingChain(t *testing.T) {
ts.AdvanceEpoch()
ts.AdvanceBlocks(ts.BlocksToSave() + 1)

// delegator should get half of the payment
// delegator should get third of the payment
res, err = ts.QueryDualstakingDelegatorRewards(delegator, provider, "")
require.Nil(ts.T, err)
require.Equal(ts.T, ts.plan.Price.Amount.QuoRaw(3).AddRaw(1), res.Rewards[0].Amount[0].Amount)
Expand Down
28 changes: 17 additions & 11 deletions x/pairing/keeper/single_provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,10 @@ func TestUnstakeStake(t *testing.T) {

ts.AdvanceEpoch()

for i := 0; i < 5; i++ {
res, err := ts.QueryPairingProvider(provider0.Addr.String(), SpecName(i))
require.NoError(t, err)
require.Equal(t, int64(1000), res.StakeEntries[0].DelegateTotal.Amount.Int64())
stakeEntries := ts.Keepers.Epochstorage.GetAllStakeEntriesForEpoch(ts.Ctx, ts.EpochStart())
require.Len(t, stakeEntries, 5)
for _, entry := range stakeEntries {
require.Equal(t, int64(1000), entry.DelegateTotal.Amount.Int64())
}

// unstake spec0 provider
Expand Down Expand Up @@ -110,13 +110,11 @@ func TestUnstakeStake(t *testing.T) {

ts.AdvanceEpoch()

res1, err = ts.QueryPairingProvider(provider0.Addr.String(), SpecName(0))
require.NoError(t, err)
require.Equal(t, int64(2500), res1.StakeEntries[0].DelegateTotal.Amount.Int64())

res1, err = ts.QueryPairingProvider(provider0.Addr.String(), SpecName(1))
require.NoError(t, err)
require.Equal(t, int64(2500), res1.StakeEntries[0].DelegateTotal.Amount.Int64())
stakeEntries = ts.Keepers.Epochstorage.GetAllStakeEntriesForEpoch(ts.Ctx, ts.EpochStart())
require.Len(t, stakeEntries, 2)
for _, entry := range stakeEntries {
require.Equal(t, int64(2500), entry.DelegateTotal.Amount.Int64())
}
}

// * unstake to see the delegations distributions
Expand Down Expand Up @@ -152,6 +150,14 @@ func TestUnstakeStakeNewVault(t *testing.T) {
for i := 0; i < 5; i++ {
_, err = ts.TxPairingUnstakeProvider(provider0.GetVaultAddr(), SpecName(i))
require.NoError(t, err)

md, err := ts.Keepers.Epochstorage.GetMetadata(ts.Ctx, provider0.Addr.String())
if i == 4 {
require.Error(t, err)
} else {
require.NoError(t, err)
require.Len(t, md.Chains, 4-i)
}
}

res, err := ts.QueryDualstakingDelegatorProviders(delegator.Addr.String())
Expand Down
17 changes: 8 additions & 9 deletions x/pairing/keeper/staking.go
Original file line number Diff line number Diff line change
Expand Up @@ -261,15 +261,14 @@ func (k Keeper) StakeNewEntry(ctx sdk.Context, validator, creator, chainID strin
}

stakeEntry := epochstoragetypes.StakeEntry{
Stake: stakeAmount,
Address: provider,
StakeAppliedBlock: stakeAppliedBlock,
Endpoints: endpointsVerified,
Geolocation: geolocation,
Chain: chainID,
DelegateTotal: sdk.NewCoin(k.stakingKeeper.BondDenom(ctx), delegateTotal),
DelegateCommission: 0,
Vault: creator, // the stake-provider TX creator is always regarded as the vault address
Stake: stakeAmount,
Address: provider,
StakeAppliedBlock: stakeAppliedBlock,
Endpoints: endpointsVerified,
Geolocation: geolocation,
Chain: chainID,
DelegateTotal: sdk.NewCoin(k.stakingKeeper.BondDenom(ctx), delegateTotal),
Vault: creator, // the stake-provider TX creator is always regarded as the vault address
}

metadata.DelegateCommission = delegationCommission
Expand Down

0 comments on commit 1071628

Please sign in to comment.