Merge PR #4788: Query genesis transactions

This commit is contained in:
colin axner 2019-08-01 11:56:50 -07:00 committed by Alexander Bezobchuk
parent fd92504f84
commit 2e3c52bae1
27 changed files with 158 additions and 58 deletions

View File

@ -0,0 +1 @@
# 3867 Allow querying for genesis transaction when height query param is set to zero.

View File

@ -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)

View File

@ -3,6 +3,7 @@ package rest
import (
"fmt"
"net/http"
"strconv"
"strings"
"github.com/gorilla/mux"
@ -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
@ -50,16 +52,11 @@ 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,
@ -67,6 +64,21 @@ func QueryTxsByEventsRequestHandlerFn(cliCtx context.CLIContext) http.HandlerFun
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
@ -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

View File

@ -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")
}

View File

@ -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())

View File

@ -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)
}

View File

@ -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)

View File

@ -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(

View File

@ -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))

View File

@ -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))

View File

@ -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))

View File

@ -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

View File

@ -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
@ -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
@ -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))

View File

@ -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"
)
@ -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

View File

@ -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
}

View File

@ -11,7 +11,7 @@ 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) {
@ -19,8 +19,10 @@ func InitGenesis(ctx sdk.Context, keeper Keeper, ak types.AccountKeeper, data Ge
return false
},
)
data.Supply.Total = totalSupply
data.Supply = data.Supply.SetTotal(totalSupply)
}
keeper.SetSupply(ctx, data.Supply)
}

View File

@ -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)
@ -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)

View File

@ -94,7 +94,7 @@ 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)
@ -102,7 +102,7 @@ func TestMintCoins(t *testing.T) {
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) })
}
@ -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))
@ -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())
}

View File

@ -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))

View File

@ -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)
}
}

View File

@ -21,9 +21,7 @@ type Keeper struct {
}
// NewKeeper creates a new Keeper instance
func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, ak types.AccountKeeper, bk types.BankKeeper,
codespace sdk.CodespaceType, maccPerms map[string][]string) Keeper {
func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, ak types.AccountKeeper, bk types.BankKeeper, maccPerms map[string][]string) Keeper {
// set the addresses
permAddrs := make(map[string]types.PermissionsForAddress)
for name, perms := range maccPerms {
@ -45,7 +43,7 @@ func (k Keeper) Logger(ctx sdk.Context) log.Logger {
}
// GetSupply retrieves the Supply from store
func (k Keeper) GetSupply(ctx sdk.Context) (supply types.Supply) {
func (k Keeper) GetSupply(ctx sdk.Context) (supply exported.SupplyI) {
store := ctx.KVStore(k.storeKey)
b := store.Get(SupplyKey)
if b == nil {
@ -56,7 +54,7 @@ func (k Keeper) GetSupply(ctx sdk.Context) (supply types.Supply) {
}
// SetSupply sets the Supply to store
func (k Keeper) SetSupply(ctx sdk.Context, supply types.Supply) {
func (k Keeper) SetSupply(ctx sdk.Context, supply exported.SupplyI) {
store := ctx.KVStore(k.storeKey)
b := k.cdc.MustMarshalBinaryLengthPrefixed(supply)
store.Set(SupplyKey, b)

View File

@ -16,7 +16,7 @@ func TestSupply(t *testing.T) {
ctx, _, keeper := createTestInput(t, false, initialPower, nAccs)
total := keeper.GetSupply(ctx).Total
total := keeper.GetSupply(ctx).GetTotal()
expectedTotal := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, initTokens.MulRaw(nAccs)))
require.Equal(t, expectedTotal, total)

View File

@ -14,10 +14,13 @@ import (
func NewQuerier(k Keeper) sdk.Querier {
return func(ctx sdk.Context, path []string, req abci.RequestQuery) (res []byte, err sdk.Error) {
switch path[0] {
case types.QueryTotalSupply:
return queryTotalSupply(ctx, req, k)
case types.QuerySupplyOf:
return querySupplyOf(ctx, req, k)
default:
return nil, sdk.ErrUnknownRequest("unknown supply query endpoint")
}
@ -32,7 +35,7 @@ func queryTotalSupply(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte,
return nil, sdk.ErrInternal(fmt.Sprintf("failed to parse params: %s", err))
}
totalSupply := k.GetSupply(ctx).Total
totalSupply := k.GetSupply(ctx).GetTotal()
start, end := client.Paginate(len(totalSupply), params.Page, params.Limit, 100)
if start < 0 || end < 0 {
@ -57,7 +60,7 @@ func querySupplyOf(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, sd
return nil, sdk.ErrInternal(fmt.Sprintf("failed to parse params: %s", err))
}
supply := k.GetSupply(ctx).Total.AmountOf(params.Denom)
supply := k.GetSupply(ctx).GetTotal().AmountOf(params.Denom)
res, err := supply.MarshalJSON()
if err != nil {

View File

@ -8,7 +8,9 @@ import (
// RegisterCodec registers the account types and interface
func RegisterCodec(cdc *codec.Codec) {
cdc.RegisterInterface((*exported.ModuleAccountI)(nil), nil)
cdc.RegisterInterface((*exported.SupplyI)(nil), nil)
cdc.RegisterConcrete(&ModuleAccount{}, "cosmos-sdk/ModuleAccount", nil)
cdc.RegisterConcrete(&Supply{}, "cosmos-sdk/Supply", nil)
}
// ModuleCdc generic sealed codec to be used throughout module

View File

@ -1,12 +1,16 @@
package types
import (
"github.com/cosmos/cosmos-sdk/x/supply/exported"
)
// GenesisState is the supply state that must be provided at genesis.
type GenesisState struct {
Supply Supply `json:"supply" yaml:"supply"`
Supply exported.SupplyI `json:"supply" yaml:"supply"`
}
// NewGenesisState creates a new genesis state.
func NewGenesisState(supply Supply) GenesisState {
func NewGenesisState(supply exported.SupplyI) GenesisState {
return GenesisState{supply}
}

View File

@ -3,30 +3,51 @@ package types
import (
"fmt"
yaml "gopkg.in/yaml.v2"
"gopkg.in/yaml.v2"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/supply/exported"
)
// Implements Delegation interface
var _ exported.SupplyI = Supply{}
// Supply represents a struct that passively keeps track of the total supply amounts in the network
type Supply struct {
Total sdk.Coins `json:"total" yaml:"total"` // total supply of tokens registered on the chain
}
// SetTotal sets the total supply.
func (supply Supply) SetTotal(total sdk.Coins) exported.SupplyI {
supply.Total = total
return supply
}
// GetTotal returns the supply total.
func (supply Supply) GetTotal() sdk.Coins {
return supply.Total
}
// NewSupply creates a new Supply instance
func NewSupply(total sdk.Coins) Supply { return Supply{total} }
func NewSupply(total sdk.Coins) exported.SupplyI {
return Supply{total}
}
// DefaultSupply creates an empty Supply
func DefaultSupply() Supply { return NewSupply(sdk.NewCoins()) }
func DefaultSupply() exported.SupplyI {
return NewSupply(sdk.NewCoins())
}
// Inflate adds coins to the total supply
func (supply *Supply) Inflate(amount sdk.Coins) {
func (supply Supply) Inflate(amount sdk.Coins) exported.SupplyI {
supply.Total = supply.Total.Add(amount)
return supply
}
// Deflate subtracts coins from the total supply
func (supply *Supply) Deflate(amount sdk.Coins) {
func (supply Supply) Deflate(amount sdk.Coins) exported.SupplyI {
supply.Total = supply.Total.Sub(amount)
return supply
}
// String returns a human readable string representation of a supplier.

View File

@ -14,7 +14,7 @@ import (
func TestSupplyMarshalYAML(t *testing.T) {
supply := DefaultSupply()
coins := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.OneInt()))
supply.Inflate(coins)
supply = supply.Inflate(coins)
bz, err := yaml.Marshal(supply)
require.NoError(t, err)