mirror of
https://github.com/0glabs/0g-chain.git
synced 2024-11-20 15:05:21 +00:00
Override original community-pool query service (#1430)
* initial version * override x/distribution community-pool query * test subset of original x/distribution queries Co-authored-by: rhuairahrighairigh <ruaridh.odonnell@gmail.com>
This commit is contained in:
parent
4c1524d7bc
commit
ad0d1f80c8
25
app/app.go
25
app/app.go
@ -90,6 +90,7 @@ import (
|
||||
|
||||
"github.com/kava-labs/kava/app/ante"
|
||||
kavaparams "github.com/kava-labs/kava/app/params"
|
||||
kavadistrquery "github.com/kava-labs/kava/app/query/distribution"
|
||||
"github.com/kava-labs/kava/x/auction"
|
||||
auctionkeeper "github.com/kava-labs/kava/x/auction/keeper"
|
||||
auctiontypes "github.com/kava-labs/kava/x/auction/types"
|
||||
@ -898,7 +899,7 @@ func NewApp(
|
||||
app.mm.RegisterRoutes(app.Router(), app.QueryRouter(), encodingConfig.Amino)
|
||||
|
||||
app.configurator = module.NewConfigurator(app.appCodec, app.MsgServiceRouter(), app.GRPCQueryRouter())
|
||||
app.mm.RegisterServices(app.configurator)
|
||||
app.RegisterServices(app.configurator)
|
||||
|
||||
// RegisterUpgradeHandlers is used for registering any on-chain upgrades.
|
||||
// It needs to be called after `app.mm` and `app.configurator` are set.
|
||||
@ -971,6 +972,28 @@ func NewApp(
|
||||
return app
|
||||
}
|
||||
|
||||
func (app *App) RegisterServices(cfg module.Configurator) {
|
||||
// Register services from all unmodified modules
|
||||
for _, module := range app.mm.Modules {
|
||||
// skip registration of distribution services
|
||||
if module.Name() == distrtypes.ModuleName {
|
||||
continue
|
||||
}
|
||||
module.RegisterServices(cfg)
|
||||
}
|
||||
|
||||
// register ditribution services except query server
|
||||
distrtypes.RegisterMsgServer(cfg.MsgServer(), distrkeeper.NewMsgServerImpl(app.distrKeeper))
|
||||
cfg.RegisterMigration(
|
||||
distrtypes.ModuleName,
|
||||
1,
|
||||
distrkeeper.NewMigrator(app.distrKeeper).Migrate1to2,
|
||||
)
|
||||
|
||||
// register fake distribution query server
|
||||
distrtypes.RegisterQueryServer(cfg.QueryServer(), kavadistrquery.NewQueryServer(app.distrKeeper, app.communityKeeper))
|
||||
}
|
||||
|
||||
// BeginBlocker contains app specific logic for the BeginBlock abci call.
|
||||
func (app *App) BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock) abci.ResponseBeginBlock {
|
||||
return app.mm.BeginBlock(ctx, req)
|
||||
|
10
app/query/distribution/expected_keepers.go
Normal file
10
app/query/distribution/expected_keepers.go
Normal file
@ -0,0 +1,10 @@
|
||||
package distribution
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
// CommunityKeeper defines the contract needed to be fulfilled for community module dependencies.
|
||||
type CommunityKeeper interface {
|
||||
GetModuleAccountBalance(sdk.Context) sdk.Coins
|
||||
}
|
38
app/query/distribution/query.go
Normal file
38
app/query/distribution/query.go
Normal file
@ -0,0 +1,38 @@
|
||||
package distribution
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
distrkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper"
|
||||
distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
|
||||
)
|
||||
|
||||
var _ distrtypes.QueryServer = &queryServer{}
|
||||
|
||||
type queryServer struct {
|
||||
distrkeeper.Keeper
|
||||
|
||||
communityKeeper CommunityKeeper
|
||||
}
|
||||
|
||||
// NewQueryServer returns a grpc query server for the distribution module.
|
||||
// It forwards most requests to the distribution keeper, except for the community pool request
|
||||
// which is mapped to the kava community module.
|
||||
func NewQueryServer(distrKeeper distrkeeper.Keeper, commKeeper CommunityKeeper) distrtypes.QueryServer {
|
||||
return &queryServer{
|
||||
Keeper: distrKeeper,
|
||||
communityKeeper: commKeeper,
|
||||
}
|
||||
}
|
||||
|
||||
// CommunityPool queries the kava community module
|
||||
// The original community pool, which is a separately accounted for portion of x/auth's fee pool
|
||||
// is replaces with the x/community module account.
|
||||
// TODO: implement legacy community pool balance query in x/community
|
||||
// To query the original community pool, including historical values, use x/community's LegacyCommunityPoolBalance
|
||||
func (q queryServer) CommunityPool(c context.Context, req *distrtypes.QueryCommunityPoolRequest) (*distrtypes.QueryCommunityPoolResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
balance := q.communityKeeper.GetModuleAccountBalance(ctx)
|
||||
return &distrtypes.QueryCommunityPoolResponse{Pool: sdk.NewDecCoinsFromCoins(balance...)}, nil
|
||||
}
|
170
app/query/distribution/query_test.go
Normal file
170
app/query/distribution/query_test.go
Normal file
@ -0,0 +1,170 @@
|
||||
package distribution_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
|
||||
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
||||
tmtime "github.com/tendermint/tendermint/types/time"
|
||||
|
||||
"github.com/kava-labs/kava/app"
|
||||
distrquery "github.com/kava-labs/kava/app/query/distribution"
|
||||
communitytypes "github.com/kava-labs/kava/x/community/types"
|
||||
)
|
||||
|
||||
type queryTestSuite struct {
|
||||
suite.Suite
|
||||
|
||||
App app.TestApp
|
||||
Ctx sdk.Context
|
||||
|
||||
queryClient distrtypes.QueryClient
|
||||
communityPoolAddress sdk.AccAddress
|
||||
}
|
||||
|
||||
func (suite *queryTestSuite) SetupTest() {
|
||||
app.SetSDKConfig()
|
||||
tApp := app.NewTestApp()
|
||||
ctx := tApp.NewContext(true, tmproto.Header{Height: 1, Time: tmtime.Now()})
|
||||
|
||||
tApp.InitializeFromGenesisStates()
|
||||
|
||||
suite.App = tApp
|
||||
suite.Ctx = ctx
|
||||
|
||||
queryHelper := baseapp.NewQueryServerTestHelper(suite.Ctx, suite.App.InterfaceRegistry())
|
||||
distrtypes.RegisterQueryServer(queryHelper, distrquery.NewQueryServer(
|
||||
tApp.GetDistrKeeper(),
|
||||
tApp.GetCommunityKeeper(),
|
||||
))
|
||||
suite.queryClient = distrtypes.NewQueryClient(queryHelper)
|
||||
suite.communityPoolAddress = tApp.GetAccountKeeper().GetModuleAddress(communitytypes.ModuleAccountName)
|
||||
}
|
||||
|
||||
func TestGRPQueryTestSuite(t *testing.T) {
|
||||
suite.Run(t, new(queryTestSuite))
|
||||
}
|
||||
|
||||
func (suite queryTestSuite) FundCommunityPool(amt sdk.Coins) {
|
||||
err := suite.App.FundModuleAccount(suite.Ctx, communitytypes.ModuleAccountName, amt)
|
||||
suite.NoError(err)
|
||||
}
|
||||
|
||||
func (suite queryTestSuite) CheckCommunityPoolBalance(expected sdk.Coins, result sdk.DecCoins) {
|
||||
actual := suite.App.GetBankKeeper().GetAllBalances(suite.Ctx, suite.communityPoolAddress)
|
||||
// check that account was properly funded
|
||||
suite.Equal(expected, actual, "unexpected community pool balance")
|
||||
|
||||
// transform the expected values to DecCoins to compare with result
|
||||
decCoins := sdk.NewDecCoinsFromCoins(expected...)
|
||||
suite.True(decCoins.IsEqual(result), "unexpected community pool query response")
|
||||
}
|
||||
|
||||
func (suite *queryTestSuite) Test_CommunityPoolOverride() {
|
||||
singleDenom := sdk.NewCoins(sdk.NewInt64Coin("ukava", 1e10))
|
||||
multiDenom := singleDenom.Add(sdk.NewInt64Coin("other-denom", 1e9))
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
funds sdk.Coins
|
||||
}{
|
||||
{"single denom", singleDenom},
|
||||
{"multiple denoms", multiDenom},
|
||||
{"no balance", sdk.NewCoins()},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
suite.Run(fmt.Sprintf("queries the correct balance - %s", tc.name), func() {
|
||||
suite.SetupTest()
|
||||
|
||||
// init community pool funds
|
||||
if !tc.funds.IsZero() {
|
||||
suite.FundCommunityPool(tc.funds)
|
||||
}
|
||||
|
||||
// query the overridden endpoint
|
||||
balance, err := suite.queryClient.CommunityPool(
|
||||
context.Background(),
|
||||
&distrtypes.QueryCommunityPoolRequest{},
|
||||
)
|
||||
suite.NoError(err)
|
||||
suite.CheckCommunityPoolBalance(tc.funds, balance.Pool)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// modified from sdk test of distribution querier
|
||||
func (suite *queryTestSuite) Test_OGDistributionQueries() {
|
||||
suite.SetupTest()
|
||||
|
||||
ctx, distrKeeper, stakingKeeper := suite.Ctx, suite.App.GetDistrKeeper(), suite.App.GetStakingKeeper()
|
||||
|
||||
// setup a validator
|
||||
addr := app.RandomAddress()
|
||||
valAddr := sdk.ValAddress(addr)
|
||||
bondDenom := stakingKeeper.BondDenom(ctx)
|
||||
|
||||
// test param queries
|
||||
params := distrtypes.Params{
|
||||
CommunityTax: sdk.ZeroDec(),
|
||||
BaseProposerReward: sdk.NewDecWithPrec(2, 1),
|
||||
BonusProposerReward: sdk.NewDecWithPrec(1, 1),
|
||||
WithdrawAddrEnabled: true,
|
||||
}
|
||||
distrKeeper.SetParams(ctx, params)
|
||||
r1, err := suite.queryClient.Params(context.Background(), &distrtypes.QueryParamsRequest{})
|
||||
suite.NoError(err)
|
||||
suite.Equal(params, r1.Params)
|
||||
|
||||
// test outstanding rewards query
|
||||
outstandingRewards := sdk.NewDecCoins(sdk.NewInt64DecCoin(bondDenom, 100), sdk.NewInt64DecCoin("other", 10))
|
||||
distrKeeper.SetValidatorOutstandingRewards(ctx, valAddr, distrtypes.ValidatorOutstandingRewards{Rewards: outstandingRewards})
|
||||
r2, err := suite.queryClient.ValidatorOutstandingRewards(context.Background(), &distrtypes.QueryValidatorOutstandingRewardsRequest{ValidatorAddress: valAddr.String()})
|
||||
suite.NoError(err)
|
||||
suite.Equal(outstandingRewards, r2.Rewards.Rewards)
|
||||
|
||||
// test validator commission query
|
||||
commission := sdk.DecCoins{{Denom: "token1", Amount: sdk.NewDec(4)}, {Denom: "token2", Amount: sdk.NewDec(2)}}
|
||||
distrKeeper.SetValidatorAccumulatedCommission(ctx, valAddr, distrtypes.ValidatorAccumulatedCommission{Commission: commission})
|
||||
r3, err := suite.queryClient.ValidatorCommission(context.Background(), &distrtypes.QueryValidatorCommissionRequest{ValidatorAddress: valAddr.String()})
|
||||
suite.NoError(err)
|
||||
suite.Equal(commission, r3.Commission.Commission)
|
||||
|
||||
// test delegator's total rewards query
|
||||
r4, err := suite.queryClient.DelegationTotalRewards(context.Background(), &distrtypes.QueryDelegationTotalRewardsRequest{DelegatorAddress: addr.String()})
|
||||
suite.NoError(err)
|
||||
suite.Equal(&distrtypes.QueryDelegationTotalRewardsResponse{}, r4)
|
||||
|
||||
// test validator slashes query with height range
|
||||
slashOne := distrtypes.NewValidatorSlashEvent(3, sdk.NewDecWithPrec(5, 1))
|
||||
slashTwo := distrtypes.NewValidatorSlashEvent(7, sdk.NewDecWithPrec(6, 1))
|
||||
distrKeeper.SetValidatorSlashEvent(ctx, valAddr, 3, 0, slashOne)
|
||||
distrKeeper.SetValidatorSlashEvent(ctx, valAddr, 7, 0, slashTwo)
|
||||
slashes := suite.getQueriedValidatorSlashes(valAddr, 0, 2)
|
||||
suite.Equal(0, len(slashes))
|
||||
slashes = suite.getQueriedValidatorSlashes(valAddr, 0, 5)
|
||||
suite.Equal([]distrtypes.ValidatorSlashEvent{slashOne}, slashes)
|
||||
slashes = suite.getQueriedValidatorSlashes(valAddr, 0, 10)
|
||||
suite.Equal([]distrtypes.ValidatorSlashEvent{slashOne, slashTwo}, slashes)
|
||||
|
||||
// non-zero delegator reward queries are not tested here.
|
||||
}
|
||||
|
||||
func (suite *queryTestSuite) getQueriedValidatorSlashes(validatorAddr sdk.ValAddress, startHeight uint64, endHeight uint64) (slashes []distrtypes.ValidatorSlashEvent) {
|
||||
result, err := suite.queryClient.ValidatorSlashes(
|
||||
context.Background(),
|
||||
&distrtypes.QueryValidatorSlashesRequest{
|
||||
ValidatorAddress: validatorAddr.String(),
|
||||
StartingHeight: startHeight,
|
||||
EndingHeight: endHeight,
|
||||
},
|
||||
)
|
||||
suite.NoError(err)
|
||||
return result.Slashes
|
||||
}
|
Loading…
Reference in New Issue
Block a user