Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Query genesis transactions #4788

Merged
merged 18 commits into from
Aug 1, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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")
alexanderbez marked this conversation as resolved.
Show resolved Hide resolved
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