-
Notifications
You must be signed in to change notification settings - Fork 170
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
incentive: set up KVStore schema, parameters and query API (#66)
- Loading branch information
1 parent
de37367
commit 5a92ef6
Showing
26 changed files
with
1,883 additions
and
75 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
syntax = "proto3"; | ||
package babylon.incentive; | ||
|
||
import "gogoproto/gogo.proto"; | ||
import "cosmos/base/v1beta1/coin.proto"; | ||
|
||
option go_package = "github.com/babylonchain/babylon/x/incentive/types"; | ||
|
||
// Gauge is an object that stores rewards to be distributed | ||
// code adapted from https://github.com/osmosis-labs/osmosis/blob/v18.0.0/proto/osmosis/incentives/gauge.proto | ||
message Gauge { | ||
// coins are coins that have been in the gauge | ||
// Can have multiple coin denoms | ||
repeated cosmos.base.v1beta1.Coin coins = 1 [ | ||
(gogoproto.nullable) = false, | ||
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" | ||
]; | ||
// distributed_coins are coins that have been distributed already | ||
repeated cosmos.base.v1beta1.Coin distributed_coins = 2 [ | ||
(gogoproto.nullable) = false, | ||
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" | ||
]; | ||
} | ||
|
||
// RewardGauge is an object that stores rewards distributed to a BTC staking/timestamping stakeholder | ||
// code adapted from https://github.com/osmosis-labs/osmosis/blob/v18.0.0/proto/osmosis/incentives/gauge.proto | ||
message RewardGauge { | ||
// coins are coins that have been in the gauge | ||
// Can have multiple coin denoms | ||
repeated cosmos.base.v1beta1.Coin coins = 1 [ | ||
(gogoproto.nullable) = false, | ||
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" | ||
]; | ||
// withdrawn_coins are coins that have been withdrawn by the stakeholder already | ||
repeated cosmos.base.v1beta1.Coin withdrawn_coins = 2 [ | ||
(gogoproto.nullable) = false, | ||
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" | ||
]; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
package datagen | ||
|
||
import ( | ||
"math/rand" | ||
|
||
itypes "github.com/babylonchain/babylon/x/incentive/types" | ||
sdk "github.com/cosmos/cosmos-sdk/types" | ||
) | ||
|
||
const ( | ||
characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" | ||
denomLen = 5 | ||
) | ||
|
||
func GenRandomDenom(r *rand.Rand) string { | ||
var result string | ||
// Generate the random string | ||
for i := 0; i < denomLen; i++ { | ||
// Generate a random index within the range of the character set | ||
index := r.Intn(len(characters)) | ||
// Add the randomly selected character to the result | ||
result += string(characters[index]) | ||
} | ||
return result | ||
} | ||
|
||
func GenRandomStakeholderType(r *rand.Rand) itypes.StakeholderType { | ||
stBytes := []byte{byte(RandomInt(r, 4))} | ||
st, err := itypes.NewStakeHolderType(stBytes) | ||
if err != nil { | ||
panic(err) // only programming error is possible | ||
} | ||
return st | ||
} | ||
|
||
func GenRandomRewardGauge(r *rand.Rand) *itypes.RewardGauge { | ||
numCoins := r.Int31n(10) + 10 | ||
coins := sdk.NewCoins() | ||
for i := int32(0); i < numCoins; i++ { | ||
demon := GenRandomDenom(r) | ||
amount := r.Int63n(10000) | ||
coin := sdk.NewInt64Coin(demon, amount) | ||
coins = coins.Add(coin) | ||
} | ||
return itypes.NewRewardGauge(coins...) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
package keeper | ||
|
||
import ( | ||
"github.com/babylonchain/babylon/x/incentive/types" | ||
"github.com/cosmos/cosmos-sdk/store/prefix" | ||
sdk "github.com/cosmos/cosmos-sdk/types" | ||
) | ||
|
||
func (k Keeper) SetBTCStakingGauge(ctx sdk.Context, height uint64, gauge *types.Gauge) { | ||
store := k.btcStakingGaugeStore(ctx) | ||
gaugeBytes := k.cdc.MustMarshal(gauge) | ||
store.Set(sdk.Uint64ToBigEndian(height), gaugeBytes) | ||
} | ||
|
||
func (k Keeper) GetBTCStakingGauge(ctx sdk.Context, height uint64) (*types.Gauge, error) { | ||
store := k.btcStakingGaugeStore(ctx) | ||
gaugeBytes := store.Get(sdk.Uint64ToBigEndian(height)) | ||
if len(gaugeBytes) == 0 { | ||
return nil, types.ErrBTCStakingGaugeNotFound | ||
} | ||
|
||
var gauge types.Gauge | ||
k.cdc.MustUnmarshal(gaugeBytes, &gauge) | ||
return &gauge, nil | ||
} | ||
|
||
// btcStakingGaugeStore returns the KVStore of the gauge of total reward for | ||
// BTC staking at each height | ||
// prefix: BTCStakingGaugeKey | ||
// key: gauge height | ||
// value: gauge of rewards for BTC staking at this height | ||
func (k Keeper) btcStakingGaugeStore(ctx sdk.Context) prefix.Store { | ||
store := ctx.KVStore(k.storeKey) | ||
return prefix.NewStore(store, types.BTCStakingGaugeKey) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
package keeper | ||
|
||
import ( | ||
"github.com/babylonchain/babylon/x/incentive/types" | ||
"github.com/cosmos/cosmos-sdk/store/prefix" | ||
sdk "github.com/cosmos/cosmos-sdk/types" | ||
) | ||
|
||
func (k Keeper) SetBTCTimestampingGauge(ctx sdk.Context, epoch uint64, gauge *types.Gauge) { | ||
store := k.btcTimestampingGaugeStore(ctx) | ||
gaugeBytes := k.cdc.MustMarshal(gauge) | ||
store.Set(sdk.Uint64ToBigEndian(epoch), gaugeBytes) | ||
} | ||
|
||
func (k Keeper) GetBTCTimestampingGauge(ctx sdk.Context, epoch uint64) (*types.Gauge, error) { | ||
store := k.btcTimestampingGaugeStore(ctx) | ||
gaugeBytes := store.Get(sdk.Uint64ToBigEndian(epoch)) | ||
if len(gaugeBytes) == 0 { | ||
return nil, types.ErrBTCTimestampingGaugeNotFound | ||
} | ||
|
||
var gauge types.Gauge | ||
k.cdc.MustUnmarshal(gaugeBytes, &gauge) | ||
return &gauge, nil | ||
} | ||
|
||
// btcTimestampingGaugeStore returns the KVStore of the gauge of total reward for | ||
// BTC timestamping at each epoch | ||
// prefix: BTCTimestampingGaugeKey | ||
// key: epoch number | ||
// value: gauge of rewards for BTC timestamping at this epoch | ||
func (k Keeper) btcTimestampingGaugeStore(ctx sdk.Context) prefix.Store { | ||
store := ctx.KVStore(k.storeKey) | ||
return prefix.NewStore(store, types.BTCTimestampingGaugeKey) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package keeper | ||
|
||
import ( | ||
"context" | ||
|
||
"github.com/babylonchain/babylon/x/incentive/types" | ||
sdk "github.com/cosmos/cosmos-sdk/types" | ||
"google.golang.org/grpc/codes" | ||
"google.golang.org/grpc/status" | ||
) | ||
|
||
var _ types.QueryServer = Keeper{} | ||
|
||
func (k Keeper) RewardGauge(goCtx context.Context, req *types.QueryRewardGaugeRequest) (*types.QueryRewardGaugeResponse, error) { | ||
if req == nil { | ||
return nil, status.Error(codes.InvalidArgument, "invalid request") | ||
} | ||
ctx := sdk.UnwrapSDKContext(goCtx) | ||
|
||
// try to cast types for fields in the request | ||
sType, err := types.NewStakeHolderTypeFromString(req.Type) | ||
if err != nil { | ||
return nil, status.Error(codes.InvalidArgument, err.Error()) | ||
} | ||
address, err := sdk.AccAddressFromBech32(req.Address) | ||
if err != nil { | ||
return nil, status.Error(codes.InvalidArgument, err.Error()) | ||
} | ||
|
||
// find reward gauge | ||
rg, err := k.GetRewardGauge(ctx, sType, address) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return &types.QueryRewardGaugeResponse{RewardGauge: rg}, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
package keeper_test | ||
|
||
import ( | ||
"math/rand" | ||
"testing" | ||
|
||
"github.com/babylonchain/babylon/testutil/datagen" | ||
testkeeper "github.com/babylonchain/babylon/testutil/keeper" | ||
"github.com/babylonchain/babylon/x/incentive/types" | ||
sdk "github.com/cosmos/cosmos-sdk/types" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func FuzzRewardGaugeQuery(f *testing.F) { | ||
datagen.AddRandomSeedsToFuzzer(f, 10) | ||
f.Fuzz(func(t *testing.T, seed int64) { | ||
r := rand.New(rand.NewSource(seed)) | ||
|
||
keeper, ctx := testkeeper.IncentiveKeeper(t) | ||
wctx := sdk.WrapSDKContext(ctx) | ||
|
||
// generate a list of random RewardGauges and insert them to KVStore | ||
rgList := []*types.RewardGauge{} | ||
sTypeList := []types.StakeholderType{} | ||
sAddrList := []sdk.AccAddress{} | ||
numRgs := datagen.RandomInt(r, 100) | ||
for i := uint64(0); i < numRgs; i++ { | ||
sType := datagen.GenRandomStakeholderType(r) | ||
sTypeList = append(sTypeList, sType) | ||
sAddr := datagen.GenRandomAccount().GetAddress() | ||
sAddrList = append(sAddrList, sAddr) | ||
rg := datagen.GenRandomRewardGauge(r) | ||
rgList = append(rgList, rg) | ||
|
||
keeper.SetRewardGauge(ctx, sType, sAddr, rg) | ||
} | ||
|
||
// query existence and assert consistency | ||
for i := range rgList { | ||
req := &types.QueryRewardGaugeRequest{ | ||
Type: sTypeList[i].String(), | ||
Address: sAddrList[i].String(), | ||
} | ||
resp, err := keeper.RewardGauge(wctx, req) | ||
require.NoError(t, err) | ||
require.True(t, resp.RewardGauge.Coins.IsEqual(rgList[i].Coins)) | ||
} | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.