Move /bank/balances/{address} REST endpoint into /x/bank (#4570)
Closes: #4560
This commit is contained in:
parent
a79749564e
commit
1e7c4dd58a
1
.pending/features/sdk/4570-Move-bank-balan
Normal file
1
.pending/features/sdk/4570-Move-bank-balan
Normal file
@ -0,0 +1 @@
|
||||
#4570 Move /bank/balances/{address} REST handler to x/bank/client/rest. The exposed interface is unchanged.
|
||||
@ -42,7 +42,6 @@ var (
|
||||
NewParams = types.NewParams
|
||||
ParamKeyTable = types.ParamKeyTable
|
||||
DefaultParams = types.DefaultParams
|
||||
NewQueryAccountParams = types.NewQueryAccountParams
|
||||
NewStdTx = types.NewStdTx
|
||||
CountSubKeys = types.CountSubKeys
|
||||
NewStdFee = types.NewStdFee
|
||||
@ -75,7 +74,6 @@ type (
|
||||
FeeCollectionKeeper = types.FeeCollectionKeeper
|
||||
GenesisState = types.GenesisState
|
||||
Params = types.Params
|
||||
QueryAccountParams = types.QueryAccountParams
|
||||
StdSignMsg = types.StdSignMsg
|
||||
StdTx = types.StdTx
|
||||
StdFee = types.StdFee
|
||||
|
||||
@ -64,50 +64,6 @@ func QueryAccountRequestHandlerFn(
|
||||
}
|
||||
}
|
||||
|
||||
// query accountREST Handler
|
||||
func QueryBalancesRequestHandlerFn(
|
||||
storeName string, decoder types.AccountDecoder, cliCtx context.CLIContext,
|
||||
) http.HandlerFunc {
|
||||
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
vars := mux.Vars(r)
|
||||
bech32addr := vars["address"]
|
||||
|
||||
addr, err := sdk.AccAddressFromBech32(bech32addr)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
res, _, err := cliCtx.QueryStore(types.AddressStoreKey(addr), storeName)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// the query will return empty if there is no data for this account
|
||||
if len(res) == 0 {
|
||||
rest.PostProcessResponse(w, cliCtx, sdk.Coins{})
|
||||
return
|
||||
}
|
||||
|
||||
// decode the value
|
||||
account, err := decoder(res)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
rest.PostProcessResponse(w, cliCtx, account.GetCoins())
|
||||
}
|
||||
}
|
||||
|
||||
// QueryTxsByTagsRequestHandlerFn implements a REST handler that searches for
|
||||
// transactions by tags.
|
||||
func QueryTxsByTagsRequestHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
|
||||
|
||||
@ -12,12 +12,6 @@ func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router, storeName string)
|
||||
"/auth/accounts/{address}",
|
||||
QueryAccountRequestHandlerFn(storeName, context.GetAccountDecoder(cliCtx.Codec), cliCtx),
|
||||
).Methods("GET")
|
||||
|
||||
// TODO: Change path or mount under x/bank if possible
|
||||
r.HandleFunc(
|
||||
"/bank/balances/{address}",
|
||||
QueryBalancesRequestHandlerFn(storeName, context.GetAccountDecoder(cliCtx.Codec), cliCtx),
|
||||
).Methods("GET")
|
||||
}
|
||||
|
||||
// RegisterTxRoutes registers all transaction routes on the provided router.
|
||||
|
||||
@ -4,9 +4,11 @@ import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
)
|
||||
|
||||
func Test_queryAccount(t *testing.T) {
|
||||
@ -20,13 +22,13 @@ func Test_queryAccount(t *testing.T) {
|
||||
require.NotNil(t, err)
|
||||
require.Nil(t, res)
|
||||
|
||||
req.Data = input.cdc.MustMarshalJSON(NewQueryAccountParams([]byte("")))
|
||||
req.Data = input.cdc.MustMarshalJSON(types.NewQueryAccountParams([]byte("")))
|
||||
res, err = queryAccount(input.ctx, req, input.ak)
|
||||
require.NotNil(t, err)
|
||||
require.Nil(t, res)
|
||||
|
||||
_, _, addr := types.KeyTestPubAddr()
|
||||
req.Data = input.cdc.MustMarshalJSON(NewQueryAccountParams(addr))
|
||||
req.Data = input.cdc.MustMarshalJSON(types.NewQueryAccountParams(addr))
|
||||
res, err = queryAccount(input.ctx, req, input.ak)
|
||||
require.NotNil(t, err)
|
||||
require.Nil(t, res)
|
||||
|
||||
@ -9,13 +9,12 @@ const (
|
||||
QueryAccount = "account"
|
||||
)
|
||||
|
||||
// defines the params for query: "custom/acc/account"
|
||||
// QueryAccountParams defines the params for querying accounts.
|
||||
type QueryAccountParams struct {
|
||||
Address sdk.AccAddress
|
||||
}
|
||||
|
||||
// NewQueryAccountParams creates a new instance of QueryAccountParams.
|
||||
func NewQueryAccountParams(addr sdk.AccAddress) QueryAccountParams {
|
||||
return QueryAccountParams{
|
||||
Address: addr,
|
||||
}
|
||||
return QueryAccountParams{Address: addr}
|
||||
}
|
||||
|
||||
@ -15,6 +15,7 @@ const (
|
||||
CodeInvalidInputsOutputs = types.CodeInvalidInputsOutputs
|
||||
ModuleName = types.ModuleName
|
||||
RouterKey = types.RouterKey
|
||||
QuerierRoute = types.QuerierRoute
|
||||
DefaultParamspace = types.DefaultParamspace
|
||||
)
|
||||
|
||||
|
||||
54
x/bank/client/rest/query.go
Normal file
54
x/bank/client/rest/query.go
Normal file
@ -0,0 +1,54 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
|
||||
"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/bank/internal/types"
|
||||
)
|
||||
|
||||
// query accountREST Handler
|
||||
func QueryBalancesRequestHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
|
||||
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
vars := mux.Vars(r)
|
||||
bech32addr := vars["address"]
|
||||
|
||||
addr, err := sdk.AccAddressFromBech32(bech32addr)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
params := types.NewQueryBalanceParams(addr)
|
||||
bz, err := cliCtx.Codec.MarshalJSON(params)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
res, _, err := cliCtx.QueryWithData("custom/bank/balances", bz)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// the query will return empty if there is no data for this account
|
||||
if len(res) == 0 {
|
||||
rest.PostProcessResponse(w, cliCtx, sdk.Coins{})
|
||||
return
|
||||
}
|
||||
|
||||
rest.PostProcessResponse(w, cliCtx, res)
|
||||
}
|
||||
}
|
||||
@ -6,7 +6,6 @@ import (
|
||||
"github.com/gorilla/mux"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/context"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/rest"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/client/utils"
|
||||
@ -17,6 +16,7 @@ import (
|
||||
// RegisterRoutes - Central function to define routes that get registered by the main application
|
||||
func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router) {
|
||||
r.HandleFunc("/bank/accounts/{address}/transfers", SendRequestHandlerFn(cliCtx)).Methods("POST")
|
||||
r.HandleFunc("/bank/balances/{address}", QueryBalancesRequestHandlerFn(cliCtx)).Methods("GET")
|
||||
}
|
||||
|
||||
// SendReq defines the properties of a send request's body.
|
||||
@ -25,12 +25,6 @@ type SendReq struct {
|
||||
Amount sdk.Coins `json:"amount"`
|
||||
}
|
||||
|
||||
var moduleCdc = codec.New()
|
||||
|
||||
func init() {
|
||||
types.RegisterCodec(moduleCdc)
|
||||
}
|
||||
|
||||
// SendRequestHandlerFn - http request handler to send coins to a address.
|
||||
func SendRequestHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
@ -21,6 +21,7 @@ import (
|
||||
type testInput struct {
|
||||
cdc *codec.Codec
|
||||
ctx sdk.Context
|
||||
k Keeper
|
||||
ak auth.AccountKeeper
|
||||
pk params.Keeper
|
||||
}
|
||||
@ -51,14 +52,15 @@ func setupTestInput() testInput {
|
||||
|
||||
ak.SetParams(ctx, auth.DefaultParams())
|
||||
|
||||
return testInput{cdc: cdc, ctx: ctx, ak: ak, pk: pk}
|
||||
bankKeeper := NewBaseKeeper(ak, pk.Subspace(types.DefaultParamspace), types.DefaultCodespace)
|
||||
bankKeeper.SetSendEnabled(ctx, true)
|
||||
|
||||
return testInput{cdc: cdc, ctx: ctx, k: bankKeeper, ak: ak, pk: pk}
|
||||
}
|
||||
|
||||
func TestKeeper(t *testing.T) {
|
||||
input := setupTestInput()
|
||||
ctx := input.ctx
|
||||
bankKeeper := NewBaseKeeper(input.ak, input.pk.Subspace(types.DefaultParamspace), types.DefaultCodespace)
|
||||
bankKeeper.SetSendEnabled(ctx, true)
|
||||
|
||||
addr := sdk.AccAddress([]byte("addr1"))
|
||||
addr2 := sdk.AccAddress([]byte("addr2"))
|
||||
@ -67,57 +69,57 @@ func TestKeeper(t *testing.T) {
|
||||
|
||||
// Test GetCoins/SetCoins
|
||||
input.ak.SetAccount(ctx, acc)
|
||||
require.True(t, bankKeeper.GetCoins(ctx, addr).IsEqual(sdk.NewCoins()))
|
||||
require.True(t, input.k.GetCoins(ctx, addr).IsEqual(sdk.NewCoins()))
|
||||
|
||||
bankKeeper.SetCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 10)))
|
||||
require.True(t, bankKeeper.GetCoins(ctx, addr).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("foocoin", 10))))
|
||||
input.k.SetCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 10)))
|
||||
require.True(t, input.k.GetCoins(ctx, addr).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("foocoin", 10))))
|
||||
|
||||
// Test HasCoins
|
||||
require.True(t, bankKeeper.HasCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 10))))
|
||||
require.True(t, bankKeeper.HasCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 5))))
|
||||
require.False(t, bankKeeper.HasCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 15))))
|
||||
require.False(t, bankKeeper.HasCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("barcoin", 5))))
|
||||
require.True(t, input.k.HasCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 10))))
|
||||
require.True(t, input.k.HasCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 5))))
|
||||
require.False(t, input.k.HasCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 15))))
|
||||
require.False(t, input.k.HasCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("barcoin", 5))))
|
||||
|
||||
// Test AddCoins
|
||||
bankKeeper.AddCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 15)))
|
||||
require.True(t, bankKeeper.GetCoins(ctx, addr).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("foocoin", 25))))
|
||||
input.k.AddCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 15)))
|
||||
require.True(t, input.k.GetCoins(ctx, addr).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("foocoin", 25))))
|
||||
|
||||
bankKeeper.AddCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("barcoin", 15)))
|
||||
require.True(t, bankKeeper.GetCoins(ctx, addr).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("barcoin", 15), sdk.NewInt64Coin("foocoin", 25))))
|
||||
input.k.AddCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("barcoin", 15)))
|
||||
require.True(t, input.k.GetCoins(ctx, addr).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("barcoin", 15), sdk.NewInt64Coin("foocoin", 25))))
|
||||
|
||||
// Test SubtractCoins
|
||||
bankKeeper.SubtractCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 10)))
|
||||
bankKeeper.SubtractCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("barcoin", 5)))
|
||||
require.True(t, bankKeeper.GetCoins(ctx, addr).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("barcoin", 10), sdk.NewInt64Coin("foocoin", 15))))
|
||||
input.k.SubtractCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 10)))
|
||||
input.k.SubtractCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("barcoin", 5)))
|
||||
require.True(t, input.k.GetCoins(ctx, addr).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("barcoin", 10), sdk.NewInt64Coin("foocoin", 15))))
|
||||
|
||||
bankKeeper.SubtractCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("barcoin", 11)))
|
||||
require.True(t, bankKeeper.GetCoins(ctx, addr).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("barcoin", 10), sdk.NewInt64Coin("foocoin", 15))))
|
||||
input.k.SubtractCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("barcoin", 11)))
|
||||
require.True(t, input.k.GetCoins(ctx, addr).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("barcoin", 10), sdk.NewInt64Coin("foocoin", 15))))
|
||||
|
||||
bankKeeper.SubtractCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("barcoin", 10)))
|
||||
require.True(t, bankKeeper.GetCoins(ctx, addr).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("foocoin", 15))))
|
||||
require.False(t, bankKeeper.HasCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("barcoin", 1))))
|
||||
input.k.SubtractCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("barcoin", 10)))
|
||||
require.True(t, input.k.GetCoins(ctx, addr).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("foocoin", 15))))
|
||||
require.False(t, input.k.HasCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("barcoin", 1))))
|
||||
|
||||
// Test SendCoins
|
||||
bankKeeper.SendCoins(ctx, addr, addr2, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 5)))
|
||||
require.True(t, bankKeeper.GetCoins(ctx, addr).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("foocoin", 10))))
|
||||
require.True(t, bankKeeper.GetCoins(ctx, addr2).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("foocoin", 5))))
|
||||
input.k.SendCoins(ctx, addr, addr2, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 5)))
|
||||
require.True(t, input.k.GetCoins(ctx, addr).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("foocoin", 10))))
|
||||
require.True(t, input.k.GetCoins(ctx, addr2).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("foocoin", 5))))
|
||||
|
||||
err2 := bankKeeper.SendCoins(ctx, addr, addr2, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 50)))
|
||||
err2 := input.k.SendCoins(ctx, addr, addr2, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 50)))
|
||||
require.Implements(t, (*sdk.Error)(nil), err2)
|
||||
require.True(t, bankKeeper.GetCoins(ctx, addr).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("foocoin", 10))))
|
||||
require.True(t, bankKeeper.GetCoins(ctx, addr2).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("foocoin", 5))))
|
||||
require.True(t, input.k.GetCoins(ctx, addr).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("foocoin", 10))))
|
||||
require.True(t, input.k.GetCoins(ctx, addr2).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("foocoin", 5))))
|
||||
|
||||
bankKeeper.AddCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("barcoin", 30)))
|
||||
bankKeeper.SendCoins(ctx, addr, addr2, sdk.NewCoins(sdk.NewInt64Coin("barcoin", 10), sdk.NewInt64Coin("foocoin", 5)))
|
||||
require.True(t, bankKeeper.GetCoins(ctx, addr).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("barcoin", 20), sdk.NewInt64Coin("foocoin", 5))))
|
||||
require.True(t, bankKeeper.GetCoins(ctx, addr2).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("barcoin", 10), sdk.NewInt64Coin("foocoin", 10))))
|
||||
input.k.AddCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("barcoin", 30)))
|
||||
input.k.SendCoins(ctx, addr, addr2, sdk.NewCoins(sdk.NewInt64Coin("barcoin", 10), sdk.NewInt64Coin("foocoin", 5)))
|
||||
require.True(t, input.k.GetCoins(ctx, addr).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("barcoin", 20), sdk.NewInt64Coin("foocoin", 5))))
|
||||
require.True(t, input.k.GetCoins(ctx, addr2).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("barcoin", 10), sdk.NewInt64Coin("foocoin", 10))))
|
||||
|
||||
// Test InputOutputCoins
|
||||
input1 := types.NewInput(addr2, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 2)))
|
||||
output1 := types.NewOutput(addr, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 2)))
|
||||
bankKeeper.InputOutputCoins(ctx, []types.Input{input1}, []types.Output{output1})
|
||||
require.True(t, bankKeeper.GetCoins(ctx, addr).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("barcoin", 20), sdk.NewInt64Coin("foocoin", 7))))
|
||||
require.True(t, bankKeeper.GetCoins(ctx, addr2).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("barcoin", 10), sdk.NewInt64Coin("foocoin", 8))))
|
||||
input.k.InputOutputCoins(ctx, []types.Input{input1}, []types.Output{output1})
|
||||
require.True(t, input.k.GetCoins(ctx, addr).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("barcoin", 20), sdk.NewInt64Coin("foocoin", 7))))
|
||||
require.True(t, input.k.GetCoins(ctx, addr2).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("barcoin", 10), sdk.NewInt64Coin("foocoin", 8))))
|
||||
|
||||
inputs := []types.Input{
|
||||
types.NewInput(addr, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 3))),
|
||||
@ -128,19 +130,18 @@ func TestKeeper(t *testing.T) {
|
||||
types.NewOutput(addr, sdk.NewCoins(sdk.NewInt64Coin("barcoin", 1))),
|
||||
types.NewOutput(addr3, sdk.NewCoins(sdk.NewInt64Coin("barcoin", 2), sdk.NewInt64Coin("foocoin", 5))),
|
||||
}
|
||||
bankKeeper.InputOutputCoins(ctx, inputs, outputs)
|
||||
require.True(t, bankKeeper.GetCoins(ctx, addr).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("barcoin", 21), sdk.NewInt64Coin("foocoin", 4))))
|
||||
require.True(t, bankKeeper.GetCoins(ctx, addr2).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("barcoin", 7), sdk.NewInt64Coin("foocoin", 6))))
|
||||
require.True(t, bankKeeper.GetCoins(ctx, addr3).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("barcoin", 2), sdk.NewInt64Coin("foocoin", 5))))
|
||||
input.k.InputOutputCoins(ctx, inputs, outputs)
|
||||
require.True(t, input.k.GetCoins(ctx, addr).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("barcoin", 21), sdk.NewInt64Coin("foocoin", 4))))
|
||||
require.True(t, input.k.GetCoins(ctx, addr2).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("barcoin", 7), sdk.NewInt64Coin("foocoin", 6))))
|
||||
require.True(t, input.k.GetCoins(ctx, addr3).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("barcoin", 2), sdk.NewInt64Coin("foocoin", 5))))
|
||||
}
|
||||
|
||||
func TestSendKeeper(t *testing.T) {
|
||||
input := setupTestInput()
|
||||
ctx := input.ctx
|
||||
paramSpace := input.pk.Subspace(types.DefaultParamspace)
|
||||
bankKeeper := NewBaseKeeper(input.ak, paramSpace, types.DefaultCodespace)
|
||||
paramSpace := input.pk.Subspace("newspace")
|
||||
sendKeeper := NewBaseSendKeeper(input.ak, paramSpace, types.DefaultCodespace)
|
||||
bankKeeper.SetSendEnabled(ctx, true)
|
||||
input.k.SetSendEnabled(ctx, true)
|
||||
|
||||
addr := sdk.AccAddress([]byte("addr1"))
|
||||
addr2 := sdk.AccAddress([]byte("addr2"))
|
||||
@ -150,7 +151,7 @@ func TestSendKeeper(t *testing.T) {
|
||||
input.ak.SetAccount(ctx, acc)
|
||||
require.True(t, sendKeeper.GetCoins(ctx, addr).IsEqual(sdk.NewCoins()))
|
||||
|
||||
bankKeeper.SetCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 10)))
|
||||
input.k.SetCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 10)))
|
||||
require.True(t, sendKeeper.GetCoins(ctx, addr).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("foocoin", 10))))
|
||||
|
||||
// Test HasCoins
|
||||
@ -159,7 +160,7 @@ func TestSendKeeper(t *testing.T) {
|
||||
require.False(t, sendKeeper.HasCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 15))))
|
||||
require.False(t, sendKeeper.HasCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("barcoin", 5))))
|
||||
|
||||
bankKeeper.SetCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 15)))
|
||||
input.k.SetCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 15)))
|
||||
|
||||
// Test SendCoins
|
||||
sendKeeper.SendCoins(ctx, addr, addr2, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 5)))
|
||||
@ -171,7 +172,7 @@ func TestSendKeeper(t *testing.T) {
|
||||
require.True(t, sendKeeper.GetCoins(ctx, addr).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("foocoin", 10))))
|
||||
require.True(t, sendKeeper.GetCoins(ctx, addr2).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("foocoin", 5))))
|
||||
|
||||
bankKeeper.AddCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("barcoin", 30)))
|
||||
input.k.AddCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("barcoin", 30)))
|
||||
sendKeeper.SendCoins(ctx, addr, addr2, sdk.NewCoins(sdk.NewInt64Coin("barcoin", 10), sdk.NewInt64Coin("foocoin", 5)))
|
||||
require.True(t, sendKeeper.GetCoins(ctx, addr).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("barcoin", 20), sdk.NewInt64Coin("foocoin", 5))))
|
||||
require.True(t, sendKeeper.GetCoins(ctx, addr2).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("barcoin", 10), sdk.NewInt64Coin("foocoin", 10))))
|
||||
@ -186,9 +187,7 @@ func TestSendKeeper(t *testing.T) {
|
||||
func TestViewKeeper(t *testing.T) {
|
||||
input := setupTestInput()
|
||||
ctx := input.ctx
|
||||
paramSpace := input.pk.Subspace(types.DefaultParamspace)
|
||||
bankKeeper := NewBaseKeeper(input.ak, paramSpace, types.DefaultCodespace)
|
||||
bankKeeper.SetSendEnabled(ctx, true)
|
||||
//paramSpace := input.pk.Subspace(types.DefaultParamspace)
|
||||
viewKeeper := NewBaseViewKeeper(input.ak, types.DefaultCodespace)
|
||||
|
||||
addr := sdk.AccAddress([]byte("addr1"))
|
||||
@ -198,7 +197,7 @@ func TestViewKeeper(t *testing.T) {
|
||||
input.ak.SetAccount(ctx, acc)
|
||||
require.True(t, viewKeeper.GetCoins(ctx, addr).IsEqual(sdk.NewCoins()))
|
||||
|
||||
bankKeeper.SetCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 10)))
|
||||
input.k.SetCoins(ctx, addr, sdk.NewCoins(sdk.NewInt64Coin("foocoin", 10)))
|
||||
require.True(t, viewKeeper.GetCoins(ctx, addr).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("foocoin", 10))))
|
||||
|
||||
// Test HasCoins
|
||||
@ -216,8 +215,6 @@ func TestVestingAccountSend(t *testing.T) {
|
||||
|
||||
origCoins := sdk.NewCoins(sdk.NewInt64Coin("stake", 100))
|
||||
sendCoins := sdk.NewCoins(sdk.NewInt64Coin("stake", 50))
|
||||
bankKeeper := NewBaseKeeper(input.ak, input.pk.Subspace(types.DefaultParamspace), types.DefaultCodespace)
|
||||
bankKeeper.SetSendEnabled(ctx, true)
|
||||
|
||||
addr1 := sdk.AccAddress([]byte("addr1"))
|
||||
addr2 := sdk.AccAddress([]byte("addr2"))
|
||||
@ -227,7 +224,7 @@ func TestVestingAccountSend(t *testing.T) {
|
||||
input.ak.SetAccount(ctx, vacc)
|
||||
|
||||
// require that no coins be sendable at the beginning of the vesting schedule
|
||||
err := bankKeeper.SendCoins(ctx, addr1, addr2, sendCoins)
|
||||
err := input.k.SendCoins(ctx, addr1, addr2, sendCoins)
|
||||
require.Error(t, err)
|
||||
|
||||
// receive some coins
|
||||
@ -236,7 +233,7 @@ func TestVestingAccountSend(t *testing.T) {
|
||||
|
||||
// require that all vested coins are spendable plus any received
|
||||
ctx = ctx.WithBlockTime(now.Add(12 * time.Hour))
|
||||
err = bankKeeper.SendCoins(ctx, addr1, addr2, sendCoins)
|
||||
err = input.k.SendCoins(ctx, addr1, addr2, sendCoins)
|
||||
vacc = input.ak.GetAccount(ctx, addr1).(*auth.ContinuousVestingAccount)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, origCoins, vacc.GetCoins())
|
||||
@ -250,8 +247,6 @@ func TestVestingAccountReceive(t *testing.T) {
|
||||
|
||||
origCoins := sdk.NewCoins(sdk.NewInt64Coin("stake", 100))
|
||||
sendCoins := sdk.NewCoins(sdk.NewInt64Coin("stake", 50))
|
||||
bankKeeper := NewBaseKeeper(input.ak, input.pk.Subspace(types.DefaultParamspace), types.DefaultCodespace)
|
||||
bankKeeper.SetSendEnabled(ctx, true)
|
||||
|
||||
addr1 := sdk.AccAddress([]byte("addr1"))
|
||||
addr2 := sdk.AccAddress([]byte("addr2"))
|
||||
@ -262,10 +257,10 @@ func TestVestingAccountReceive(t *testing.T) {
|
||||
acc := input.ak.NewAccountWithAddress(ctx, addr2)
|
||||
input.ak.SetAccount(ctx, vacc)
|
||||
input.ak.SetAccount(ctx, acc)
|
||||
bankKeeper.SetCoins(ctx, addr2, origCoins)
|
||||
input.k.SetCoins(ctx, addr2, origCoins)
|
||||
|
||||
// send some coins to the vesting account
|
||||
bankKeeper.SendCoins(ctx, addr2, addr1, sendCoins)
|
||||
input.k.SendCoins(ctx, addr2, addr1, sendCoins)
|
||||
|
||||
// require the coins are spendable
|
||||
vacc = input.ak.GetAccount(ctx, addr1).(*auth.ContinuousVestingAccount)
|
||||
@ -284,8 +279,6 @@ func TestDelegateCoins(t *testing.T) {
|
||||
|
||||
origCoins := sdk.NewCoins(sdk.NewInt64Coin("stake", 100))
|
||||
delCoins := sdk.NewCoins(sdk.NewInt64Coin("stake", 50))
|
||||
bankKeeper := NewBaseKeeper(input.ak, input.pk.Subspace(types.DefaultParamspace), types.DefaultCodespace)
|
||||
bankKeeper.SetSendEnabled(ctx, true)
|
||||
|
||||
addr1 := sdk.AccAddress([]byte("addr1"))
|
||||
addr2 := sdk.AccAddress([]byte("addr2"))
|
||||
@ -296,18 +289,18 @@ func TestDelegateCoins(t *testing.T) {
|
||||
acc := input.ak.NewAccountWithAddress(ctx, addr2)
|
||||
input.ak.SetAccount(ctx, vacc)
|
||||
input.ak.SetAccount(ctx, acc)
|
||||
bankKeeper.SetCoins(ctx, addr2, origCoins)
|
||||
input.k.SetCoins(ctx, addr2, origCoins)
|
||||
|
||||
ctx = ctx.WithBlockTime(now.Add(12 * time.Hour))
|
||||
|
||||
// require the ability for a non-vesting account to delegate
|
||||
_, err := bankKeeper.DelegateCoins(ctx, addr2, delCoins)
|
||||
_, err := input.k.DelegateCoins(ctx, addr2, delCoins)
|
||||
acc = input.ak.GetAccount(ctx, addr2)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, delCoins, acc.GetCoins())
|
||||
|
||||
// require the ability for a vesting account to delegate
|
||||
_, err = bankKeeper.DelegateCoins(ctx, addr1, delCoins)
|
||||
_, err = input.k.DelegateCoins(ctx, addr1, delCoins)
|
||||
vacc = input.ak.GetAccount(ctx, addr1).(*auth.ContinuousVestingAccount)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, delCoins, vacc.GetCoins())
|
||||
@ -321,8 +314,6 @@ func TestUndelegateCoins(t *testing.T) {
|
||||
|
||||
origCoins := sdk.NewCoins(sdk.NewInt64Coin("stake", 100))
|
||||
delCoins := sdk.NewCoins(sdk.NewInt64Coin("stake", 50))
|
||||
bankKeeper := NewBaseKeeper(input.ak, input.pk.Subspace(types.DefaultParamspace), types.DefaultCodespace)
|
||||
bankKeeper.SetSendEnabled(ctx, true)
|
||||
|
||||
addr1 := sdk.AccAddress([]byte("addr1"))
|
||||
addr2 := sdk.AccAddress([]byte("addr2"))
|
||||
@ -333,27 +324,27 @@ func TestUndelegateCoins(t *testing.T) {
|
||||
acc := input.ak.NewAccountWithAddress(ctx, addr2)
|
||||
input.ak.SetAccount(ctx, vacc)
|
||||
input.ak.SetAccount(ctx, acc)
|
||||
bankKeeper.SetCoins(ctx, addr2, origCoins)
|
||||
input.k.SetCoins(ctx, addr2, origCoins)
|
||||
|
||||
ctx = ctx.WithBlockTime(now.Add(12 * time.Hour))
|
||||
|
||||
// require the ability for a non-vesting account to delegate
|
||||
_, err := bankKeeper.DelegateCoins(ctx, addr2, delCoins)
|
||||
_, err := input.k.DelegateCoins(ctx, addr2, delCoins)
|
||||
require.NoError(t, err)
|
||||
|
||||
// require the ability for a non-vesting account to undelegate
|
||||
_, err = bankKeeper.UndelegateCoins(ctx, addr2, delCoins)
|
||||
_, err = input.k.UndelegateCoins(ctx, addr2, delCoins)
|
||||
require.NoError(t, err)
|
||||
|
||||
acc = input.ak.GetAccount(ctx, addr2)
|
||||
require.Equal(t, origCoins, acc.GetCoins())
|
||||
|
||||
// require the ability for a vesting account to delegate
|
||||
_, err = bankKeeper.DelegateCoins(ctx, addr1, delCoins)
|
||||
_, err = input.k.DelegateCoins(ctx, addr1, delCoins)
|
||||
require.NoError(t, err)
|
||||
|
||||
// require the ability for a vesting account to undelegate
|
||||
_, err = bankKeeper.UndelegateCoins(ctx, addr1, delCoins)
|
||||
_, err = input.k.UndelegateCoins(ctx, addr1, delCoins)
|
||||
require.NoError(t, err)
|
||||
|
||||
vacc = input.ak.GetAccount(ctx, addr1).(*auth.ContinuousVestingAccount)
|
||||
|
||||
45
x/bank/internal/keeper/querier.go
Normal file
45
x/bank/internal/keeper/querier.go
Normal file
@ -0,0 +1,45 @@
|
||||
package keeper
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/bank/internal/types"
|
||||
)
|
||||
|
||||
const (
|
||||
QueryBalance = "balances"
|
||||
)
|
||||
|
||||
// NewQuerier returns a new sdk.Keeper instance.
|
||||
func NewQuerier(k Keeper) sdk.Querier {
|
||||
return func(ctx sdk.Context, path []string, req abci.RequestQuery) ([]byte, sdk.Error) {
|
||||
switch path[0] {
|
||||
case QueryBalance:
|
||||
return queryBalance(ctx, req, k)
|
||||
|
||||
default:
|
||||
return nil, sdk.ErrUnknownRequest("unknown bank query endpoint")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// queryBalance fetch an account's balance for the supplied height.
|
||||
// Height and account address are passed as first and second path components respectively.
|
||||
func queryBalance(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, sdk.Error) {
|
||||
var params types.QueryBalanceParams
|
||||
|
||||
if err := types.ModuleCdc.UnmarshalJSON(req.Data, ¶ms); err != nil {
|
||||
return nil, sdk.ErrInternal(fmt.Sprintf("failed to parse params: %s", err))
|
||||
}
|
||||
|
||||
bz, err := codec.MarshalJSONIndent(types.ModuleCdc, k.GetCoins(ctx, params.Address))
|
||||
if err != nil {
|
||||
return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error()))
|
||||
}
|
||||
|
||||
return bz, nil
|
||||
}
|
||||
59
x/bank/internal/keeper/querier_test.go
Normal file
59
x/bank/internal/keeper/querier_test.go
Normal file
@ -0,0 +1,59 @@
|
||||
package keeper
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/bank/internal/types"
|
||||
)
|
||||
|
||||
func TestBalances(t *testing.T) {
|
||||
input := setupTestInput()
|
||||
req := abci.RequestQuery{
|
||||
Path: fmt.Sprintf("custom/bank/%s", QueryBalance),
|
||||
Data: []byte{},
|
||||
}
|
||||
|
||||
querier := NewQuerier(input.k)
|
||||
|
||||
res, err := querier(input.ctx, []string{"balances"}, req)
|
||||
require.NotNil(t, err)
|
||||
require.Nil(t, res)
|
||||
|
||||
_, _, addr := authtypes.KeyTestPubAddr()
|
||||
req.Data = input.cdc.MustMarshalJSON(types.NewQueryBalanceParams(addr))
|
||||
res, err = querier(input.ctx, []string{"balances"}, req)
|
||||
require.Nil(t, err) // the account does not exist, no error returned anyway
|
||||
require.NotNil(t, res)
|
||||
|
||||
var coins sdk.Coins
|
||||
require.NoError(t, input.cdc.UnmarshalJSON(res, &coins))
|
||||
require.True(t, coins.IsZero())
|
||||
|
||||
acc := input.ak.NewAccountWithAddress(input.ctx, addr)
|
||||
acc.SetCoins(sdk.NewCoins(sdk.NewInt64Coin("foo", 10)))
|
||||
input.ak.SetAccount(input.ctx, acc)
|
||||
res, err = querier(input.ctx, []string{"balances"}, req)
|
||||
require.Nil(t, err)
|
||||
require.NotNil(t, res)
|
||||
require.NoError(t, input.cdc.UnmarshalJSON(res, &coins))
|
||||
require.True(t, coins.AmountOf("foo").Equal(sdk.NewInt(10)))
|
||||
}
|
||||
|
||||
func TestQuerierRouteNotFound(t *testing.T) {
|
||||
input := setupTestInput()
|
||||
req := abci.RequestQuery{
|
||||
Path: "custom/bank/notfound",
|
||||
Data: []byte{},
|
||||
}
|
||||
|
||||
querier := NewQuerier(input.k)
|
||||
_, err := querier(input.ctx, []string{"notfound"}, req)
|
||||
require.Error(t, err)
|
||||
}
|
||||
@ -2,5 +2,6 @@ package types
|
||||
|
||||
const (
|
||||
// module name
|
||||
ModuleName = "bank"
|
||||
ModuleName = "bank"
|
||||
QuerierRoute = ModuleName
|
||||
)
|
||||
|
||||
15
x/bank/internal/types/querier.go
Normal file
15
x/bank/internal/types/querier.go
Normal file
@ -0,0 +1,15 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
// QueryBalanceParams defines the params for querying an account balance.
|
||||
type QueryBalanceParams struct {
|
||||
Address sdk.AccAddress
|
||||
}
|
||||
|
||||
// NewQueryBalanceParams creates a new instance of QueryBalanceParams.
|
||||
func NewQueryBalanceParams(addr sdk.AccAddress) QueryBalanceParams {
|
||||
return QueryBalanceParams{Address: addr}
|
||||
}
|
||||
@ -26,8 +26,6 @@ var (
|
||||
// app module basics object
|
||||
type AppModuleBasic struct{}
|
||||
|
||||
var _ module.AppModuleBasic = AppModuleBasic{}
|
||||
|
||||
// module name
|
||||
func (AppModuleBasic) Name() string { return ModuleName }
|
||||
|
||||
@ -94,10 +92,12 @@ func (AppModule) Route() string { return RouterKey }
|
||||
func (am AppModule) NewHandler() sdk.Handler { return NewHandler(am.keeper) }
|
||||
|
||||
// module querier route name
|
||||
func (AppModule) QuerierRoute() string { return "" }
|
||||
func (AppModule) QuerierRoute() string { return RouterKey }
|
||||
|
||||
// module querier
|
||||
func (AppModule) NewQuerierHandler() sdk.Querier { return nil }
|
||||
func (am AppModule) NewQuerierHandler() sdk.Querier {
|
||||
return keeper.NewQuerier(am.keeper)
|
||||
}
|
||||
|
||||
// module init-genesis
|
||||
func (am AppModule) InitGenesis(ctx sdk.Context, data json.RawMessage) []abci.ValidatorUpdate {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user