Show height on legacy REST endpoints (#7997)
* Fix showing height in rest endpoints * Fix query height * Manually inject req.Height * Small tweaks * Use withHeight Co-authored-by: Aleksandr Bezobchuk <alexanderbez@users.noreply.github.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
This commit is contained in:
parent
251a27d104
commit
74435137e9
|
@ -382,6 +382,11 @@ func (app *BaseApp) snapshot(height int64) {
|
||||||
func (app *BaseApp) Query(req abci.RequestQuery) abci.ResponseQuery {
|
func (app *BaseApp) Query(req abci.RequestQuery) abci.ResponseQuery {
|
||||||
defer telemetry.MeasureSince(time.Now(), "abci", "query")
|
defer telemetry.MeasureSince(time.Now(), "abci", "query")
|
||||||
|
|
||||||
|
// when a client did not provide a query height, manually inject the latest
|
||||||
|
if req.Height == 0 {
|
||||||
|
req.Height = app.LastBlockHeight()
|
||||||
|
}
|
||||||
|
|
||||||
// handle gRPC routes first rather than calling splitPath because '/' characters
|
// handle gRPC routes first rather than calling splitPath because '/' characters
|
||||||
// are used as part of gRPC paths
|
// are used as part of gRPC paths
|
||||||
if grpcHandler := app.grpcQueryRouter.Route(req.Path); grpcHandler != nil {
|
if grpcHandler := app.grpcQueryRouter.Route(req.Path); grpcHandler != nil {
|
||||||
|
@ -742,11 +747,6 @@ func handleQueryStore(app *BaseApp, path []string, req abci.RequestQuery) abci.R
|
||||||
|
|
||||||
req.Path = "/" + strings.Join(path[1:], "/")
|
req.Path = "/" + strings.Join(path[1:], "/")
|
||||||
|
|
||||||
// when a client did not provide a query height, manually inject the latest
|
|
||||||
if req.Height == 0 {
|
|
||||||
req.Height = app.LastBlockHeight()
|
|
||||||
}
|
|
||||||
|
|
||||||
if req.Height <= 1 && req.Prove {
|
if req.Height <= 1 && req.Prove {
|
||||||
return sdkerrors.QueryResult(
|
return sdkerrors.QueryResult(
|
||||||
sdkerrors.Wrap(
|
sdkerrors.Wrap(
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ErrInvalidAccount returns a standardized error reflecting that a given
|
|
||||||
// account address does not exist.
|
|
||||||
func ErrInvalidAccount(addr sdk.AccAddress) error {
|
|
||||||
return fmt.Errorf(`no account with address %s was found in the state.
|
|
||||||
Are you sure there has been a transaction involving it?`, addr)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ErrVerifyCommit returns a common error reflecting that the blockchain commit at a given
|
|
||||||
// height can't be verified. The reason is that the base checkpoint of the certifier is
|
|
||||||
// newer than the given height
|
|
||||||
func ErrVerifyCommit(height int64) error {
|
|
||||||
return fmt.Errorf(`the height of base truststore in the light client is higher than height %d.
|
|
||||||
Can't verify blockchain proof at this height. Please set --trust-node to true and try again`, height)
|
|
||||||
}
|
|
|
@ -11,7 +11,6 @@ import (
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/client"
|
"github.com/cosmos/cosmos-sdk/client"
|
||||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||||
"github.com/cosmos/cosmos-sdk/codec/legacy"
|
|
||||||
"github.com/cosmos/cosmos-sdk/types/rest"
|
"github.com/cosmos/cosmos-sdk/types/rest"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -68,7 +67,7 @@ func getBlock(clientCtx client.Context, height *int64) ([]byte, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return legacy.Cdc.MarshalJSON(res)
|
return clientCtx.LegacyAmino.MarshalJSON(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the current blockchain height
|
// get the current blockchain height
|
||||||
|
|
|
@ -29,7 +29,7 @@ func (s *IntegrationTestSuite) SetupSuite() {
|
||||||
s.cfg = cfg
|
s.cfg = cfg
|
||||||
s.network = network.New(s.T(), cfg)
|
s.network = network.New(s.T(), cfg)
|
||||||
|
|
||||||
_, err := s.network.WaitForHeight(1)
|
_, err := s.network.WaitForHeight(2)
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,14 +43,26 @@ func (s *IntegrationTestSuite) TestQueryBalancesRequestHandlerFn() {
|
||||||
baseURL := val.APIAddress
|
baseURL := val.APIAddress
|
||||||
|
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
name string
|
name string
|
||||||
url string
|
url string
|
||||||
respType fmt.Stringer
|
expHeight int64
|
||||||
expected fmt.Stringer
|
respType fmt.Stringer
|
||||||
|
expected fmt.Stringer
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
"total account balance",
|
"total account balance",
|
||||||
|
fmt.Sprintf("%s/bank/balances/%s", baseURL, val.Address),
|
||||||
|
-1,
|
||||||
|
&sdk.Coins{},
|
||||||
|
sdk.NewCoins(
|
||||||
|
sdk.NewCoin(fmt.Sprintf("%stoken", val.Moniker), s.cfg.AccountTokens),
|
||||||
|
sdk.NewCoin(s.cfg.BondDenom, s.cfg.StakingTokens.Sub(s.cfg.BondedTokens)),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"total account balance with height",
|
||||||
fmt.Sprintf("%s/bank/balances/%s?height=1", baseURL, val.Address),
|
fmt.Sprintf("%s/bank/balances/%s?height=1", baseURL, val.Address),
|
||||||
|
1,
|
||||||
&sdk.Coins{},
|
&sdk.Coins{},
|
||||||
sdk.NewCoins(
|
sdk.NewCoins(
|
||||||
sdk.NewCoin(fmt.Sprintf("%stoken", val.Moniker), s.cfg.AccountTokens),
|
sdk.NewCoin(fmt.Sprintf("%stoken", val.Moniker), s.cfg.AccountTokens),
|
||||||
|
@ -59,13 +71,15 @@ func (s *IntegrationTestSuite) TestQueryBalancesRequestHandlerFn() {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"total account balance of a specific denom",
|
"total account balance of a specific denom",
|
||||||
fmt.Sprintf("%s/bank/balances/%s?height=1&denom=%s", baseURL, val.Address, s.cfg.BondDenom),
|
fmt.Sprintf("%s/bank/balances/%s?denom=%s", baseURL, val.Address, s.cfg.BondDenom),
|
||||||
|
-1,
|
||||||
&sdk.Coin{},
|
&sdk.Coin{},
|
||||||
sdk.NewCoin(s.cfg.BondDenom, s.cfg.StakingTokens.Sub(s.cfg.BondedTokens)),
|
sdk.NewCoin(s.cfg.BondDenom, s.cfg.StakingTokens.Sub(s.cfg.BondedTokens)),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"total account balance of a bogus denom",
|
"total account balance of a bogus denom",
|
||||||
fmt.Sprintf("%s/bank/balances/%s?height=1&denom=foobar", baseURL, val.Address),
|
fmt.Sprintf("%s/bank/balances/%s?denom=foobar", baseURL, val.Address),
|
||||||
|
-1,
|
||||||
&sdk.Coin{},
|
&sdk.Coin{},
|
||||||
sdk.NewCoin("foobar", sdk.ZeroInt()),
|
sdk.NewCoin("foobar", sdk.ZeroInt()),
|
||||||
},
|
},
|
||||||
|
@ -74,12 +88,23 @@ func (s *IntegrationTestSuite) TestQueryBalancesRequestHandlerFn() {
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
tc := tc
|
tc := tc
|
||||||
s.Run(tc.name, func() {
|
s.Run(tc.name, func() {
|
||||||
resp, err := rest.GetRequest(tc.url)
|
respJSON, err := rest.GetRequest(tc.url)
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
|
|
||||||
bz, err := rest.ParseResponseWithHeight(val.ClientCtx.LegacyAmino, resp)
|
var resp = rest.ResponseWithHeight{}
|
||||||
|
err = val.ClientCtx.LegacyAmino.UnmarshalJSON(respJSON, &resp)
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
s.Require().NoError(val.ClientCtx.LegacyAmino.UnmarshalJSON(bz, tc.respType))
|
|
||||||
|
// Check height.
|
||||||
|
if tc.expHeight >= 0 {
|
||||||
|
s.Require().Equal(resp.Height, tc.expHeight)
|
||||||
|
} else {
|
||||||
|
// To avoid flakiness, just test that height is positive.
|
||||||
|
s.Require().Greater(resp.Height, int64(0))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check result.
|
||||||
|
s.Require().NoError(val.ClientCtx.LegacyAmino.UnmarshalJSON(resp.Result, tc.respType))
|
||||||
s.Require().Equal(tc.expected.String(), tc.respType.String())
|
s.Require().Equal(tc.expected.String(), tc.respType.String())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue