REST bank transfers fail due to encoding. (#6536)
Bank module REST endpoint bank/accounts/{addr}/transfers was returning invalid StdTx format.
This commit is contained in:
parent
37cc04081e
commit
8f96ec0585
|
@ -177,6 +177,8 @@ be used to retrieve the actual proposal `Content`. Also the `NewMsgSubmitProposa
|
|||
|
||||
### Bug Fixes
|
||||
|
||||
* (x/bank) [\#6536](https://github.com/cosmos/cosmos-sdk/pull/6536) Fix bug in `WriteGeneratedTxResponse` function used by multiple
|
||||
REST endpoints. Now it writes a Tx in StdTx format.
|
||||
* (x/staking) [\#6529](https://github.com/cosmos/cosmos-sdk/pull/6529) Export validator addresses (previously was empty).
|
||||
* (export) [\#6510](https://github.com/cosmos/cosmos-sdk/pull/6510/) Field TimeIotaMs now is included in genesis file while exporting.
|
||||
* (client) [\#6402](https://github.com/cosmos/cosmos-sdk/issues/6402) Fix `keys add` `--algo` flag which only worked for Tendermint's `secp256k1` default key signing algorithm.
|
||||
|
|
|
@ -188,7 +188,7 @@ func WriteGeneratedTxResponse(
|
|||
return
|
||||
}
|
||||
|
||||
output, err := ctx.JSONMarshaler.MarshalJSON(tx)
|
||||
output, err := ctx.JSONMarshaler.MarshalJSON(tx.GetTx())
|
||||
if rest.CheckInternalServerError(w, err) {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
package rest
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
@ -442,3 +443,23 @@ func GetRequest(url string) ([]byte, error) {
|
|||
|
||||
return body, nil
|
||||
}
|
||||
|
||||
// PostRequest defines a wrapper around an HTTP POST request with a provided URL and data.
|
||||
// An error is returned if the request or reading the body fails.
|
||||
func PostRequest(url string, contentType string, data []byte) ([]byte, error) {
|
||||
res, err := http.Post(url, contentType, bytes.NewBuffer(data)) // nolint:gosec
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error while sending post request: %w", err)
|
||||
}
|
||||
|
||||
bz, err := ioutil.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error reading response body: %w", err)
|
||||
}
|
||||
|
||||
if err = res.Body.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return bz, nil
|
||||
}
|
||||
|
|
|
@ -0,0 +1,106 @@
|
|||
package rest_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/simapp"
|
||||
"github.com/cosmos/cosmos-sdk/testutil"
|
||||
"github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/errors"
|
||||
"github.com/cosmos/cosmos-sdk/types/rest"
|
||||
authclient "github.com/cosmos/cosmos-sdk/x/auth/client"
|
||||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
bankrest "github.com/cosmos/cosmos-sdk/x/bank/client/rest"
|
||||
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||
)
|
||||
|
||||
func (s *IntegrationTestSuite) TestCoinSend() {
|
||||
encodingConfig := simapp.MakeEncodingConfig()
|
||||
authclient.Codec = encodingConfig.Marshaler
|
||||
|
||||
val := s.network.Validators[0]
|
||||
|
||||
account, err := getAccountInfo(val)
|
||||
s.Require().NoError(err)
|
||||
|
||||
sendReq := generateSendReq(
|
||||
account,
|
||||
types.Coins{types.NewCoin(s.cfg.BondDenom, types.TokensFromConsensusPower(1))},
|
||||
)
|
||||
|
||||
stdTx, err := submitSendReq(val, sendReq)
|
||||
s.Require().NoError(err)
|
||||
|
||||
s.Require().Nil(stdTx.Signatures)
|
||||
s.Require().Equal([]types.Msg{
|
||||
&banktypes.MsgSend{
|
||||
FromAddress: account.GetAddress(),
|
||||
ToAddress: account.GetAddress(),
|
||||
Amount: sendReq.Amount,
|
||||
},
|
||||
}, stdTx.GetMsgs())
|
||||
}
|
||||
|
||||
func submitSendReq(val *testutil.Validator, req bankrest.SendReq) (authtypes.StdTx, error) {
|
||||
url := fmt.Sprintf("%s/bank/accounts/%s/transfers", val.APIAddress, val.Address)
|
||||
|
||||
bz, err := val.ClientCtx.JSONMarshaler.MarshalJSON(req)
|
||||
if err != nil {
|
||||
return authtypes.StdTx{}, errors.Wrap(err, "error encoding SendReq to json")
|
||||
}
|
||||
|
||||
res, err := rest.PostRequest(url, "application/json", bz)
|
||||
if err != nil {
|
||||
return authtypes.StdTx{}, err
|
||||
}
|
||||
|
||||
var tx authtypes.StdTx
|
||||
err = val.ClientCtx.JSONMarshaler.UnmarshalJSON(res, &tx)
|
||||
if err != nil {
|
||||
return authtypes.StdTx{}, errors.Wrap(err, "error unmarshaling to StdTx SendReq response")
|
||||
}
|
||||
|
||||
return tx, nil
|
||||
}
|
||||
|
||||
func generateSendReq(from authtypes.AccountI, amount types.Coins) bankrest.SendReq {
|
||||
baseReq := rest.NewBaseReq(
|
||||
from.GetAddress().String(),
|
||||
"someMemo",
|
||||
"some-id",
|
||||
"10000",
|
||||
fmt.Sprintf("%f", 1.0),
|
||||
from.GetAccountNumber(),
|
||||
from.GetSequence(),
|
||||
types.NewCoins(),
|
||||
nil,
|
||||
false,
|
||||
)
|
||||
|
||||
return bankrest.SendReq{
|
||||
BaseReq: baseReq,
|
||||
Amount: amount,
|
||||
}
|
||||
}
|
||||
|
||||
func getAccountInfo(val *testutil.Validator) (authtypes.AccountI, error) {
|
||||
url := fmt.Sprintf("%s/auth/accounts/%s", val.APIAddress, val.Address)
|
||||
|
||||
resp, err := rest.GetRequest(url)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
bz, err := rest.ParseResponseWithHeight(val.ClientCtx.JSONMarshaler, resp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var acc authtypes.AccountI
|
||||
err = val.ClientCtx.JSONMarshaler.UnmarshalJSON(bz, &acc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return acc, nil
|
||||
}
|
Loading…
Reference in New Issue