Skip to content

Commit

Permalink
Merge PR cosmos#4788: Query genesis transactions
Browse files Browse the repository at this point in the history
  • Loading branch information
colin-axner authored and alexanderbez committed Aug 1, 2019
1 parent fd92504 commit 2e3c52b
Show file tree
Hide file tree
Showing 27 changed files with 158 additions and 58 deletions.
1 change: 1 addition & 0 deletions .pending/improvements/rest/3867-Allow-querying-
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# 3867 Allow querying for genesis transaction when height query param is set to zero.
2 changes: 1 addition & 1 deletion simapp/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ func NewSimApp(
// add keepers
app.accountKeeper = auth.NewAccountKeeper(app.cdc, keys[auth.StoreKey], authSubspace, auth.ProtoBaseAccount)
app.bankKeeper = bank.NewBaseKeeper(app.accountKeeper, bankSubspace, bank.DefaultCodespace, app.ModuleAccountAddrs())
app.supplyKeeper = supply.NewKeeper(app.cdc, keys[supply.StoreKey], app.accountKeeper, app.bankKeeper, supply.DefaultCodespace, maccPerms)
app.supplyKeeper = supply.NewKeeper(app.cdc, keys[supply.StoreKey], app.accountKeeper, app.bankKeeper, maccPerms)
stakingKeeper := staking.NewKeeper(app.cdc, keys[staking.StoreKey], tkeys[staking.TStoreKey],
app.supplyKeeper, stakingSubspace, staking.DefaultCodespace)
app.mintKeeper = mint.NewKeeper(app.cdc, keys[mint.StoreKey], mintSubspace, &stakingKeeper, app.supplyKeeper, auth.FeeCollectorName)
Expand Down
34 changes: 23 additions & 11 deletions x/auth/client/rest/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package rest
import (
"fmt"
"net/http"
"strconv"
"strings"

"github.com/gorilla/mux"
Expand All @@ -12,6 +13,7 @@ import (
"github.com/cosmos/cosmos-sdk/types/rest"
"github.com/cosmos/cosmos-sdk/x/auth/client/utils"
"github.com/cosmos/cosmos-sdk/x/auth/types"
genutilrest "github.com/cosmos/cosmos-sdk/x/genutil/client/rest"
)

// query accountREST Handler
Expand Down Expand Up @@ -50,23 +52,33 @@ func QueryAccountRequestHandlerFn(storeName string, cliCtx context.CLIContext) h
}
}

// QueryTxsByEventsRequestHandlerFn implements a REST handler that searches for
// transactions by events.
func QueryTxsByEventsRequestHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
// QueryTxsHandlerFn implements a REST handler that searches for transactions.
// Genesis transactions are returned if the height parameter is set to zero,
// otherwise the transactions are searched for by events.
func QueryTxsRequestHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var (
tags []string
txs []sdk.TxResponse
page, limit int
)

err := r.ParseForm()
if err != nil {
rest.WriteErrorResponse(w, http.StatusBadRequest,
sdk.AppendMsgToErr("could not parse query parameters", err.Error()))
return
}

// if the height query param is set to zero, query for genesis transactions
heightStr := r.FormValue("height")
if heightStr != "" {
if height, err := strconv.ParseInt(heightStr, 10, 64); err == nil && height == 0 {
genutilrest.QueryGenesisTxs(cliCtx, w)
return
}
}

var (
events []string
txs []sdk.TxResponse
page, limit int
)

cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r)
if !ok {
return
Expand All @@ -77,13 +89,13 @@ func QueryTxsByEventsRequestHandlerFn(cliCtx context.CLIContext) http.HandlerFun
return
}

tags, page, limit, err = rest.ParseHTTPArgs(r)
events, page, limit, err = rest.ParseHTTPArgs(r)
if err != nil {
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
return
}

searchResult, err := utils.QueryTxsByEvents(cliCtx, tags, page, limit)
searchResult, err := utils.QueryTxsByEvents(cliCtx, events, page, limit)
if err != nil {
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
return
Expand Down
2 changes: 1 addition & 1 deletion x/auth/client/rest/rest.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router, storeName string)
// RegisterTxRoutes registers all transaction routes on the provided router.
func RegisterTxRoutes(cliCtx context.CLIContext, r *mux.Router) {
r.HandleFunc("/txs/{hash}", QueryTxRequestHandlerFn(cliCtx)).Methods("GET")
r.HandleFunc("/txs", QueryTxsByEventsRequestHandlerFn(cliCtx)).Methods("GET")
r.HandleFunc("/txs", QueryTxsRequestHandlerFn(cliCtx)).Methods("GET")
r.HandleFunc("/txs", BroadcastTxRequest(cliCtx)).Methods("POST")
r.HandleFunc("/txs/encode", EncodeTxRequestHandlerFn(cliCtx)).Methods("POST")
}
2 changes: 1 addition & 1 deletion x/distribution/keeper/test_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ func CreateTestInputAdvanced(t *testing.T, isCheckTx bool, initPower int64,
staking.NotBondedPoolName: {supply.Burner, supply.Staking},
staking.BondedPoolName: {supply.Burner, supply.Staking},
}
supplyKeeper := supply.NewKeeper(cdc, keySupply, accountKeeper, bankKeeper, supply.DefaultCodespace, maccPerms)
supplyKeeper := supply.NewKeeper(cdc, keySupply, accountKeeper, bankKeeper, maccPerms)

sk := staking.NewKeeper(cdc, keyStaking, tkeyStaking, supplyKeeper, pk.Subspace(staking.DefaultParamspace), staking.DefaultCodespace)
sk.SetParams(ctx, staking.DefaultParams())
Expand Down
41 changes: 41 additions & 0 deletions x/genutil/client/rest/query.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package rest

import (
"net/http"

"github.com/cosmos/cosmos-sdk/client/context"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/rest"
"github.com/cosmos/cosmos-sdk/x/genutil/types"
)

// QueryGenesisTxs writes the genesis transactions to the response if no error
// occurs.
func QueryGenesisTxs(cliCtx context.CLIContext, w http.ResponseWriter) {
resultGenesis, err := cliCtx.Client.Genesis()
if err != nil {
rest.WriteErrorResponse(w, http.StatusInternalServerError,
sdk.AppendMsgToErr("could not retrieve genesis from client", err.Error()))
return
}

appState, err := types.GenesisStateFromGenDoc(cliCtx.Codec, *resultGenesis.Genesis)
if err != nil {
rest.WriteErrorResponse(w, http.StatusInternalServerError,
sdk.AppendMsgToErr("could not decode genesis doc", err.Error()))
return
}

genState := types.GetGenesisStateFromAppState(cliCtx.Codec, appState)
genTxs := make([]sdk.Tx, len(genState.GenTxs))
for i, tx := range genState.GenTxs {
err := cliCtx.Codec.UnmarshalJSON(tx, &genTxs[i])
if err != nil {
rest.WriteErrorResponse(w, http.StatusInternalServerError,
sdk.AppendMsgToErr("could not decode genesis transaction", err.Error()))
return
}
}

rest.PostProcessResponse(w, cliCtx, genTxs)
}
2 changes: 1 addition & 1 deletion x/gov/test_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ func getMockApp(t *testing.T, numGenAccs int, genState GenesisState, genAccs []a
staking.NotBondedPoolName: {supply.Burner, supply.Staking},
staking.BondedPoolName: {supply.Burner, supply.Staking},
}
supplyKeeper := supply.NewKeeper(mApp.Cdc, keySupply, mApp.AccountKeeper, bk, supply.DefaultCodespace, maccPerms)
supplyKeeper := supply.NewKeeper(mApp.Cdc, keySupply, mApp.AccountKeeper, bk, maccPerms)
sk := staking.NewKeeper(mApp.Cdc, keyStaking, tKeyStaking, supplyKeeper, pk.Subspace(staking.DefaultParamspace), staking.DefaultCodespace)

keeper := NewKeeper(mApp.Cdc, keyGov, pk, pk.Subspace(DefaultParamspace), supplyKeeper, sk, DefaultCodespace, rtr)
Expand Down
2 changes: 1 addition & 1 deletion x/mint/internal/keeper/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ func newTestInput(t *testing.T) testInput {
staking.NotBondedPoolName: {supply.Burner, supply.Staking},
staking.BondedPoolName: {supply.Burner, supply.Staking},
}
supplyKeeper := supply.NewKeeper(types.ModuleCdc, keySupply, accountKeeper, bankKeeper, supply.DefaultCodespace, maccPerms)
supplyKeeper := supply.NewKeeper(types.ModuleCdc, keySupply, accountKeeper, bankKeeper, maccPerms)
supplyKeeper.SetSupply(ctx, supply.NewSupply(sdk.Coins{}))

stakingKeeper := staking.NewKeeper(
Expand Down
2 changes: 1 addition & 1 deletion x/slashing/app_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ func getMockApp(t *testing.T) (*mock.App, staking.Keeper, Keeper) {
staking.NotBondedPoolName: {supply.Burner, supply.Staking},
staking.BondedPoolName: {supply.Burner, supply.Staking},
}
supplyKeeper := supply.NewKeeper(mapp.Cdc, keySupply, mapp.AccountKeeper, bankKeeper, supply.DefaultCodespace, maccPerms)
supplyKeeper := supply.NewKeeper(mapp.Cdc, keySupply, mapp.AccountKeeper, bankKeeper, maccPerms)
stakingKeeper := staking.NewKeeper(mapp.Cdc, keyStaking, tkeyStaking, supplyKeeper, mapp.ParamsKeeper.Subspace(staking.DefaultParamspace), staking.DefaultCodespace)
keeper := NewKeeper(mapp.Cdc, keySlashing, stakingKeeper, mapp.ParamsKeeper.Subspace(DefaultParamspace), DefaultCodespace)
mapp.Router().AddRoute(staking.RouterKey, staking.NewHandler(stakingKeeper))
Expand Down
2 changes: 1 addition & 1 deletion x/slashing/internal/keeper/test_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ func CreateTestInput(t *testing.T, defaults types.Params) (sdk.Context, bank.Kee
staking.NotBondedPoolName: {supply.Burner, supply.Staking},
staking.BondedPoolName: {supply.Burner, supply.Staking},
}
supplyKeeper := supply.NewKeeper(cdc, keySupply, accountKeeper, bk, supply.DefaultCodespace, maccPerms)
supplyKeeper := supply.NewKeeper(cdc, keySupply, accountKeeper, bk, maccPerms)

totalSupply := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, InitTokens.MulRaw(int64(len(Addrs)))))
supplyKeeper.SetSupply(ctx, supply.NewSupply(totalSupply))
Expand Down
2 changes: 1 addition & 1 deletion x/staking/app_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func getMockApp(t *testing.T) (*mock.App, Keeper) {
types.NotBondedPoolName: {supply.Burner, supply.Staking},
types.BondedPoolName: {supply.Burner, supply.Staking},
}
supplyKeeper := supply.NewKeeper(mApp.Cdc, keySupply, mApp.AccountKeeper, bankKeeper, supply.DefaultCodespace, maccPerms)
supplyKeeper := supply.NewKeeper(mApp.Cdc, keySupply, mApp.AccountKeeper, bankKeeper, maccPerms)
keeper := NewKeeper(mApp.Cdc, keyStaking, tkeyStaking, supplyKeeper, mApp.ParamsKeeper.Subspace(DefaultParamspace), DefaultCodespace)

mApp.Router().AddRoute(RouterKey, NewHandler(keeper))
Expand Down
2 changes: 1 addition & 1 deletion x/staking/keeper/pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ func (k Keeper) TotalBondedTokens(ctx sdk.Context) sdk.Int {

// StakingTokenSupply staking tokens from the total supply
func (k Keeper) StakingTokenSupply(ctx sdk.Context) sdk.Int {
return k.supplyKeeper.GetSupply(ctx).Total.AmountOf(k.BondDenom(ctx))
return k.supplyKeeper.GetSupply(ctx).GetTotal().AmountOf(k.BondDenom(ctx))
}

// BondedRatio the fraction of the staking tokens which are currently bonded
Expand Down
6 changes: 2 additions & 4 deletions x/staking/keeper/test_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import (
"github.com/cosmos/cosmos-sdk/x/params"
"github.com/cosmos/cosmos-sdk/x/staking/types"
"github.com/cosmos/cosmos-sdk/x/supply"
"github.com/cosmos/cosmos-sdk/x/supply/exported"
)

// dummy addresses used for testing
Expand Down Expand Up @@ -70,8 +69,7 @@ func MakeTestCodec() *codec.Codec {
// Register AppAccount
cdc.RegisterInterface((*auth.Account)(nil), nil)
cdc.RegisterConcrete(&auth.BaseAccount{}, "test/staking/BaseAccount", nil)
cdc.RegisterInterface((*exported.ModuleAccountI)(nil), nil)
cdc.RegisterConcrete(&supply.ModuleAccount{}, "test/staking/ModuleAccount", nil)
supply.RegisterCodec(cdc)
codec.RegisterCrypto(cdc)

return cdc
Expand Down Expand Up @@ -139,7 +137,7 @@ func CreateTestInput(t *testing.T, isCheckTx bool, initPower int64) (sdk.Context
types.NotBondedPoolName: {supply.Burner, supply.Staking},
types.BondedPoolName: {supply.Burner, supply.Staking},
}
supplyKeeper := supply.NewKeeper(cdc, keySupply, accountKeeper, bk, supply.DefaultCodespace, maccPerms)
supplyKeeper := supply.NewKeeper(cdc, keySupply, accountKeeper, bk, maccPerms)

initTokens := sdk.TokensFromConsensusPower(initPower)
initCoins := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, initTokens))
Expand Down
3 changes: 1 addition & 2 deletions x/staking/types/expected_keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
authexported "github.com/cosmos/cosmos-sdk/x/auth/exported"
stakingexported "github.com/cosmos/cosmos-sdk/x/staking/exported"
"github.com/cosmos/cosmos-sdk/x/supply"
supplyexported "github.com/cosmos/cosmos-sdk/x/supply/exported"
)

Expand All @@ -21,7 +20,7 @@ type AccountKeeper interface {

// SupplyKeeper defines the expected supply Keeper (noalias)
type SupplyKeeper interface {
GetSupply(ctx sdk.Context) supply.Supply
GetSupply(ctx sdk.Context) supplyexported.SupplyI

GetModuleAddress(name string) sdk.AccAddress
GetModuleAccount(ctx sdk.Context, moduleName string) supplyexported.ModuleAccountI
Expand Down
20 changes: 19 additions & 1 deletion x/supply/exported/exported.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,29 @@
package exported

import "github.com/cosmos/cosmos-sdk/x/auth/exported"
import (
sdk "github.com/cosmos/cosmos-sdk/types"

"github.com/cosmos/cosmos-sdk/x/auth/exported"
)

// ModuleAccountI defines an account interface for modules that hold tokens in an escrow
type ModuleAccountI interface {
exported.Account

GetName() string
GetPermissions() []string
HasPermission(string) bool
}

// SupplyI defines an inflationary supply interface for modules that handle
// token supply.
type SupplyI interface {
GetTotal() sdk.Coins
SetTotal(total sdk.Coins) SupplyI

Inflate(amount sdk.Coins) SupplyI
Deflate(amount sdk.Coins) SupplyI

String() string
ValidateBasic() error
}
6 changes: 4 additions & 2 deletions x/supply/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,18 @@ import (
// CONTRACT: all types of accounts must have been already initialized/created
func InitGenesis(ctx sdk.Context, keeper Keeper, ak types.AccountKeeper, data GenesisState) {
// manually set the total supply based on accounts if not provided
if data.Supply.Total.Empty() {
if data.Supply.GetTotal().Empty() {
var totalSupply sdk.Coins
ak.IterateAccounts(ctx,
func(acc authexported.Account) (stop bool) {
totalSupply = totalSupply.Add(acc.GetCoins())
return false
},
)
data.Supply.Total = totalSupply

data.Supply = data.Supply.SetTotal(totalSupply)
}

keeper.SetSupply(ctx, data.Supply)
}

Expand Down
5 changes: 3 additions & 2 deletions x/supply/internal/keeper/bank.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,8 @@ func (k Keeper) MintCoins(ctx sdk.Context, moduleName string, amt sdk.Coins) sdk

// update total supply
supply := k.GetSupply(ctx)
supply.Inflate(amt)
supply = supply.Inflate(amt)

k.SetSupply(ctx, supply)

logger := k.Logger(ctx)
Expand Down Expand Up @@ -135,7 +136,7 @@ func (k Keeper) BurnCoins(ctx sdk.Context, moduleName string, amt sdk.Coins) sdk

// update total supply
supply := k.GetSupply(ctx)
supply.Deflate(amt)
supply = supply.Deflate(amt)
k.SetSupply(ctx, supply)

logger := k.Logger(ctx)
Expand Down
16 changes: 8 additions & 8 deletions x/supply/internal/keeper/bank_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,15 +94,15 @@ func TestMintCoins(t *testing.T) {
err := keeper.MintCoins(ctx, types.Minter, initCoins)
require.NoError(t, err)
require.Equal(t, initCoins, getCoinsByName(ctx, keeper, types.Minter))
require.Equal(t, initialSupply.Total.Add(initCoins), keeper.GetSupply(ctx).Total)
require.Equal(t, initialSupply.GetTotal().Add(initCoins), keeper.GetSupply(ctx).GetTotal())

// test same functionality on module account with multiple permissions
initialSupply = keeper.GetSupply(ctx)

err = keeper.MintCoins(ctx, multiPermAcc.GetName(), initCoins)
require.NoError(t, err)
require.Equal(t, initCoins, getCoinsByName(ctx, keeper, multiPermAcc.GetName()))
require.Equal(t, initialSupply.Total.Add(initCoins), keeper.GetSupply(ctx).Total)
require.Equal(t, initialSupply.GetTotal().Add(initCoins), keeper.GetSupply(ctx).GetTotal())

require.Panics(t, func() { keeper.MintCoins(ctx, types.Burner, initCoins) })
}
Expand All @@ -115,22 +115,22 @@ func TestBurnCoins(t *testing.T) {
keeper.SetModuleAccount(ctx, burnerAcc)

initialSupply := keeper.GetSupply(ctx)
initialSupply.Inflate(initCoins)
initialSupply = initialSupply.Inflate(initCoins)
keeper.SetSupply(ctx, initialSupply)

require.Error(t, keeper.BurnCoins(ctx, "", initCoins), "no module account")
require.Panics(t, func() { keeper.BurnCoins(ctx, types.Minter, initCoins) }, "invalid permission")
require.Panics(t, func() { keeper.BurnCoins(ctx, randomPerm, initialSupply.Total) }, "random permission")
require.Panics(t, func() { keeper.BurnCoins(ctx, types.Burner, initialSupply.Total) }, "insufficient coins")
require.Panics(t, func() { keeper.BurnCoins(ctx, randomPerm, initialSupply.GetTotal()) }, "random permission")
require.Panics(t, func() { keeper.BurnCoins(ctx, types.Burner, initialSupply.GetTotal()) }, "insufficient coins")

err := keeper.BurnCoins(ctx, types.Burner, initCoins)
require.NoError(t, err)
require.Equal(t, sdk.Coins(nil), getCoinsByName(ctx, keeper, types.Burner))
require.Equal(t, initialSupply.Total.Sub(initCoins), keeper.GetSupply(ctx).Total)
require.Equal(t, initialSupply.GetTotal().Sub(initCoins), keeper.GetSupply(ctx).GetTotal())

// test same functionality on module account with multiple permissions
initialSupply = keeper.GetSupply(ctx)
initialSupply.Inflate(initCoins)
initialSupply = initialSupply.Inflate(initCoins)
keeper.SetSupply(ctx, initialSupply)

require.NoError(t, multiPermAcc.SetCoins(initCoins))
Expand All @@ -139,5 +139,5 @@ func TestBurnCoins(t *testing.T) {
err = keeper.BurnCoins(ctx, multiPermAcc.GetName(), initCoins)
require.NoError(t, err)
require.Equal(t, sdk.Coins(nil), getCoinsByName(ctx, keeper, multiPermAcc.GetName()))
require.Equal(t, initialSupply.Total.Sub(initCoins), keeper.GetSupply(ctx).Total)
require.Equal(t, initialSupply.GetTotal().Sub(initCoins), keeper.GetSupply(ctx).GetTotal())
}
2 changes: 1 addition & 1 deletion x/supply/internal/keeper/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ func createTestInput(t *testing.T, isCheckTx bool, initPower int64, nAccs int64)
multiPerm: {types.Minter, types.Burner, types.Staking},
randomPerm: {"random"},
}
keeper := NewKeeper(cdc, keySupply, ak, bk, DefaultCodespace, maccPerms)
keeper := NewKeeper(cdc, keySupply, ak, bk, maccPerms)
totalSupply := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, valTokens.MulRaw(nAccs)))
keeper.SetSupply(ctx, types.NewSupply(totalSupply))

Expand Down
4 changes: 2 additions & 2 deletions x/supply/internal/keeper/invariants.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,12 @@ func TotalSupply(k Keeper) sdk.Invariant {
return false
})

broken := !expectedTotal.IsEqual(supply.Total)
broken := !expectedTotal.IsEqual(supply.GetTotal())

return sdk.FormatInvariant(types.ModuleName, "total supply",
fmt.Sprintf(
"\tsum of accounts coins: %v\n"+
"\tsupply.Total: %v\n",
expectedTotal, supply.Total), broken)
expectedTotal, supply.GetTotal()), broken)
}
}
Loading

0 comments on commit 2e3c52b

Please sign in to comment.