Skip to content

Commit

Permalink
impl wip! keeper version without msg server or protos
Browse files Browse the repository at this point in the history
  • Loading branch information
Unique-Divine committed Dec 28, 2023
1 parent 42e4214 commit 31d3bdb
Show file tree
Hide file tree
Showing 7 changed files with 231 additions and 16 deletions.
12 changes: 7 additions & 5 deletions app/keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -357,18 +357,20 @@ func (app *NibiruApp) InitKeepers(
appCodec, keys[spottypes.StoreKey], app.GetSubspace(spottypes.ModuleName),
app.AccountKeeper, app.BankKeeper, app.DistrKeeper)

app.SudoKeeper = keeper.NewKeeper(
appCodec, keys[sudotypes.StoreKey],
)

app.OracleKeeper = oraclekeeper.NewKeeper(appCodec, keys[oracletypes.StoreKey],
app.AccountKeeper, app.BankKeeper, app.DistrKeeper, app.stakingKeeper, distrtypes.ModuleName,
app.AccountKeeper, app.BankKeeper, app.DistrKeeper, app.stakingKeeper,
app.SudoKeeper,
distrtypes.ModuleName,
)

app.EpochsKeeper = epochskeeper.NewKeeper(
appCodec, keys[epochstypes.StoreKey],
)

app.SudoKeeper = keeper.NewKeeper(
appCodec, keys[sudotypes.StoreKey],
)

app.PerpKeeperV2 = perpkeeper.NewKeeper(
appCodec, keys[perptypes.StoreKey],
app.AccountKeeper, app.BankKeeper, app.OracleKeeper, app.EpochsKeeper,
Expand Down
22 changes: 18 additions & 4 deletions x/oracle/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,13 @@ type Keeper struct {
bankKeeper types.BankKeeper
distrKeeper types.DistributionKeeper
StakingKeeper types.StakingKeeper
SudoKeeper types.SudoKeeper

distrModuleName string

// Extends the Keeper with sudo functions. See sudo.go.
Admin admin

Params collections.Item[types.Params]
ExchangeRates collections.Map[asset.Pair, types.DatedPrice]
FeederDelegations collections.Map[sdk.ValAddress, sdk.AccAddress]
Expand All @@ -45,23 +49,31 @@ type Keeper struct {
}

// NewKeeper constructs a new keeper for oracle
func NewKeeper(cdc codec.BinaryCodec, storeKey storetypes.StoreKey,
func NewKeeper(
cdc codec.BinaryCodec,
storeKey storetypes.StoreKey,

accountKeeper types.AccountKeeper,
bankKeeper types.BankKeeper, distrKeeper types.DistributionKeeper,
stakingKeeper types.StakingKeeper, distrName string,
bankKeeper types.BankKeeper,
distrKeeper types.DistributionKeeper,
stakingKeeper types.StakingKeeper,
sudoKeeper types.SudoKeeper,

distrName string,
) Keeper {
// ensure oracle module account is set
if addr := accountKeeper.GetModuleAddress(types.ModuleName); addr == nil {
panic(fmt.Sprintf("%s module account has not been set", types.ModuleName))
}

return Keeper{
k := Keeper{
cdc: cdc,
storeKey: storeKey,
AccountKeeper: accountKeeper,
bankKeeper: bankKeeper,
distrKeeper: distrKeeper,
StakingKeeper: stakingKeeper,
SudoKeeper: sudoKeeper,
distrModuleName: distrName,
Params: collections.NewItem(storeKey, 11, collections.ProtoValueEncoder[types.Params](cdc)),
ExchangeRates: collections.NewMap(storeKey, 1, asset.PairKeyEncoder, collections.ProtoValueEncoder[types.DatedPrice](cdc)),
Expand All @@ -76,6 +88,8 @@ func NewKeeper(cdc codec.BinaryCodec, storeKey storetypes.StoreKey,
collections.Uint64KeyEncoder, collections.ProtoValueEncoder[types.Rewards](cdc)),
RewardsID: collections.NewSequence(storeKey, 9),
}
k.Admin = admin{&k}
return k
}

// Logger returns a module-specific logger.
Expand Down
109 changes: 109 additions & 0 deletions x/oracle/keeper/sudo.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
package keeper

import (
"fmt"
"time"

sdkmath "cosmossdk.io/math"

sdk "github.com/cosmos/cosmos-sdk/types"

"github.com/NibiruChain/nibiru/x/common/asset"
oracletypes "github.com/NibiruChain/nibiru/x/oracle/types"
)

// Extends the Keeper with admin functions. Admin is syntactic sugar to separate
// admin calls off from the other Keeper methods.
//
// These Admin functions should:
// 1. Not be called in other methods in the x/perp module.
// 2. Only be callable from the x/sudo root or sudo contracts.
//
// The intention behind "admin" is to make it more obvious to the developer that
// an unsafe function is being used when it's called from "OracleKeeper.Admin"
type admin struct{ *Keeper }

type PartialOracleParams struct {
VotePeriod *sdkmath.Int `json:"vote_period,omitempty"`
VoteThreshold *sdk.Dec `json:"vote_threshold,omitempty"`
RewardBand *sdk.Dec `json:"reward_band,omitempty"`
Whitelist []string `json:"whitelist,omitempty"`
SlashFraction *sdk.Dec `json:"slash_fraction,omitempty"`
SlashWindow *sdkmath.Int `json:"slash_window,omitempty"`
MinValidPerWindow *sdk.Dec `json:"min_valid_per_window,omitempty"`
TwapLookbackWindow *sdkmath.Int `json:"twap_lookback_window,omitempty"`
MinVoters *sdkmath.Int `json:"min_voters,omitempty"`
ValidatorFeeRatio *sdk.Dec `json:"validator_fee_ratio,omitempty"`
}

func (k admin) EditOracleParams(
ctx sdk.Context, newParams PartialOracleParams, sender sdk.AccAddress,
) error {
if err := k.SudoKeeper.CheckPermissions(sender, ctx); err != nil {
return err
}

params, err := k.Params.Get(ctx)
if err != nil {
// TODO: use typed error
return fmt.Errorf("get oracle params error: %s", err.Error())
}

mergedParams := newParams.mergeOracleParams(params)
k.UpdateParams(ctx, mergedParams)
return nil
}

// mergeOracleParams: Takes the givne oracle params and merges them into the
// existing partial params, keeping any existing values that are note set in the
// partial msg
func (msg PartialOracleParams) mergeOracleParams(
oracleParams oracletypes.Params,
) oracletypes.Params {
if msg.VotePeriod != nil {
oracleParams.VotePeriod = msg.VotePeriod.Uint64()
}

if msg.VoteThreshold != nil {
oracleParams.VoteThreshold = *msg.VoteThreshold
}

if msg.RewardBand != nil {
oracleParams.RewardBand = *msg.RewardBand
}

if msg.Whitelist != nil {
whitelist := make([]asset.Pair, len(msg.Whitelist))
for i, pair := range msg.Whitelist {
whitelist[i] = asset.MustNewPair(pair)
}

oracleParams.Whitelist = whitelist
}

if msg.SlashFraction != nil {
oracleParams.SlashFraction = *msg.SlashFraction
}

if msg.SlashWindow != nil {
oracleParams.SlashWindow = msg.SlashWindow.Uint64()
}

if msg.MinValidPerWindow != nil {
oracleParams.MinValidPerWindow = *msg.MinValidPerWindow
}

if msg.TwapLookbackWindow != nil {
oracleParams.TwapLookbackWindow = time.Duration(msg.TwapLookbackWindow.Int64())
}

if msg.MinVoters != nil {
oracleParams.MinVoters = msg.MinVoters.Uint64()
}

if msg.ValidatorFeeRatio != nil {
oracleParams.ValidatorFeeRatio = *msg.ValidatorFeeRatio
}

return oracleParams
}
65 changes: 65 additions & 0 deletions x/oracle/keeper/sudo_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package keeper_test

import (
"testing"
"time"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/stretchr/testify/suite"

"github.com/NibiruChain/nibiru/x/common/testutil"
"github.com/NibiruChain/nibiru/x/common/testutil/testapp"
oraclekeeper "github.com/NibiruChain/nibiru/x/oracle/keeper"
)

func TestSuiteOracleExecutor_RunAll(t *testing.T) {
suite.Run(t, new(SuiteOracleSudo))
}

type SuiteOracleSudo struct {
suite.Suite
}

func (s *SuiteOracleSudo) TestEditOracleParams() {
nibiru, ctx := testapp.NewNibiruTestAppAndContext()

// Change to all non-defaults to test EditOracleParams as a setter .
votePeriod := sdk.NewInt(1_234)
voteThreshold := sdk.MustNewDecFromStr("0.4")
rewardBand := sdk.MustNewDecFromStr("0.5")
whitelist := []string{"aave:usdc", "sol:usdc"}
slashFraction := sdk.MustNewDecFromStr("0.5")
slashWindow := sdk.NewInt(2)
minValidPerWindow := sdk.MustNewDecFromStr("0.5")
twapLookbackWindow := sdk.NewInt(int64(time.Second * 30))
minVoters := sdk.NewInt(2)
validatorFeeRatio := sdk.MustNewDecFromStr("0.7")
partialParams := oraclekeeper.PartialOracleParams{
VotePeriod: &votePeriod,
VoteThreshold: &voteThreshold,
RewardBand: &rewardBand,
Whitelist: whitelist,
SlashFraction: &slashFraction,
SlashWindow: &slashWindow,
MinValidPerWindow: &minValidPerWindow,
TwapLookbackWindow: &twapLookbackWindow,
MinVoters: &minVoters,
ValidatorFeeRatio: &validatorFeeRatio,
}

// TODO: Verify that params before were not equal

invalidSender := testutil.AccAddress()
err := nibiru.OracleKeeper.Admin.EditOracleParams(
ctx, partialParams, invalidSender,
)
s.Error(err)

okSender := testapp.DefaultSudoRoot()
err = nibiru.OracleKeeper.Admin.EditOracleParams(
ctx, partialParams, okSender,
)
s.NoError(err)

// call admin method without err
}
23 changes: 21 additions & 2 deletions x/oracle/keeper/test_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ import (

"github.com/NibiruChain/nibiru/x/common/denoms"
"github.com/NibiruChain/nibiru/x/oracle/types"
"github.com/NibiruChain/nibiru/x/sudo"
sudokeeper "github.com/NibiruChain/nibiru/x/sudo/keeper"
sudotypes "github.com/NibiruChain/nibiru/x/sudo/types"
dbm "github.com/cometbft/cometbft-db"
"github.com/cometbft/cometbft/crypto"
"github.com/cometbft/cometbft/crypto/secp256k1"
Expand Down Expand Up @@ -51,6 +54,7 @@ var ModuleBasics = module.NewBasicManager(
distr.AppModuleBasic{},
staking.AppModuleBasic{},
params.AppModuleBasic{},
sudo.AppModuleBasic{},
)

// MakeTestCodec nolint
Expand Down Expand Up @@ -123,6 +127,7 @@ type TestFixture struct {
OracleKeeper Keeper
StakingKeeper stakingkeeper.Keeper
DistrKeeper distrkeeper.Keeper
SudoKeeper types.SudoKeeper
}

// CreateTestFixture nolint
Expand All @@ -135,6 +140,7 @@ func CreateTestFixture(t *testing.T) TestFixture {
keyOracle := sdk.NewKVStoreKey(types.StoreKey)
keyStaking := sdk.NewKVStoreKey(stakingtypes.StoreKey)
keyDistr := sdk.NewKVStoreKey(distrtypes.StoreKey)
keySudo := sdk.NewKVStoreKey(sudotypes.StoreKey)

db := dbm.NewMemDB()
ms := store.NewCommitMultiStore(db)
Expand Down Expand Up @@ -224,11 +230,15 @@ func CreateTestFixture(t *testing.T) TestFixture {

bankKeeper.SendCoinsFromModuleToModule(ctx, faucetAccountName, stakingtypes.NotBondedPoolName, sdk.NewCoins(sdk.NewCoin(denoms.NIBI, InitTokens.MulRaw(int64(len(Addrs))))))

sudoKeeper := sudokeeper.NewKeeper(appCodec, keySudo)
sudoAcc := authtypes.NewEmptyModuleAccount(sudotypes.ModuleName)

accountKeeper.SetModuleAccount(ctx, feeCollectorAcc)
accountKeeper.SetModuleAccount(ctx, bondPool)
accountKeeper.SetModuleAccount(ctx, notBondedPool)
accountKeeper.SetModuleAccount(ctx, distrAcc)
accountKeeper.SetModuleAccount(ctx, oracleAcc)
accountKeeper.SetModuleAccount(ctx, sudoAcc)

for _, addr := range Addrs {
accountKeeper.SetAccount(ctx, authtypes.NewBaseAccountWithAddress(addr))
Expand All @@ -243,6 +253,7 @@ func CreateTestFixture(t *testing.T) TestFixture {
bankKeeper,
distrKeeper,
stakingKeeper,
sudoKeeper,
distrtypes.ModuleName,
)

Expand All @@ -254,11 +265,19 @@ func CreateTestFixture(t *testing.T) TestFixture {

keeper.Params.Set(ctx, defaults)

return TestFixture{ctx, legacyAmino, accountKeeper, bankKeeper, keeper, *stakingKeeper, distrKeeper}
return TestFixture{
ctx, legacyAmino, accountKeeper, bankKeeper,
keeper,
*stakingKeeper,
distrKeeper,
sudoKeeper,
}
}

// NewTestMsgCreateValidator test msg creator
func NewTestMsgCreateValidator(address sdk.ValAddress, pubKey cryptotypes.PubKey, amt sdk.Int) *stakingtypes.MsgCreateValidator {
func NewTestMsgCreateValidator(
address sdk.ValAddress, pubKey cryptotypes.PubKey, amt sdk.Int,
) *stakingtypes.MsgCreateValidator {
commission := stakingtypes.NewCommissionRates(sdk.ZeroDec(), sdk.ZeroDec(), sdk.ZeroDec())
msg, _ := stakingtypes.NewMsgCreateValidator(
address, pubKey, sdk.NewCoin(denoms.NIBI, amt),
Expand Down
7 changes: 7 additions & 0 deletions x/oracle/types/expected_keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,10 @@ type BankKeeper interface {
// only used for simulation
SpendableCoins(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins
}

type SudoKeeper interface {
// CheckPermissions Checks if a contract is contained within the set of sudo
// contracts defined in the x/sudo module. These smart contracts are able to
// execute certain permissioned functions.
CheckPermissions(contract sdk.AccAddress, ctx sdk.Context) error
}
9 changes: 4 additions & 5 deletions x/perp/v2/keeper/admin.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,11 @@ import (
// admin calls off from the other Keeper methods.
//
// These Admin functions should:
// 1. Not be wired into the MsgServer.
// 2. Not be called in other methods in the x/perp module.
// 3. Only be callable from nibiru/wasmbinding via sudo contracts.
// 1. Not be called in other methods in the x/perp module.
// 2. Only be callable from the x/sudo root or sudo contracts.
//
// The intention here is to make it more obvious to the developer that an unsafe
// function is being used when it's called from the PerpKeeper.Admin struct.
// The intention behind "admin" is to make it more obvious to the developer that
// an unsafe function is being used when it's called from "PerpKeeper.Admin"
type admin struct{ *Keeper }

// WithdrawFromPerpFund sends funds from the Perp Fund to the "to" address.
Expand Down

0 comments on commit 31d3bdb

Please sign in to comment.