Skip to content

Commit

Permalink
Merge PR #5865: Proto Client Migration: x/bank
Browse files Browse the repository at this point in the history
  • Loading branch information
alexanderbez authored Mar 26, 2020
2 parents b4e0c33 + fb599ad commit 6a9c8bc
Show file tree
Hide file tree
Showing 32 changed files with 1,839 additions and 166 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ older clients.

### API Breaking Changes

* (baseapp) [\#5865](https://github.com/cosmos/cosmos-sdk/pull/5865) The `SimulationResponse` returned from tx simulation is now JSON encoded instead of Amino binary.
* [\#5719](https://github.com/cosmos/cosmos-sdk/pull/5719) Bump Go requirement to 1.14+
* (x/params) [\#5619](https://github.com/cosmos/cosmos-sdk/pull/5619) The `x/params` keeper now accepts a `codec.Marshaller` instead of
a reference to an amino codec. Amino is still used for JSON serialization.
Expand Down
13 changes: 9 additions & 4 deletions baseapp/abci.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ func (app *BaseApp) CheckTx(req abci.RequestCheckTx) abci.ResponseCheckTx {
GasUsed: int64(gInfo.GasUsed), // TODO: Should type accept unsigned ints?
Log: result.Log,
Data: result.Data,
Events: result.Events.ToABCIEvents(),
Events: result.Events,
}
}

Expand All @@ -214,7 +214,7 @@ func (app *BaseApp) DeliverTx(req abci.RequestDeliverTx) abci.ResponseDeliverTx
GasUsed: int64(gInfo.GasUsed), // TODO: Should type accept unsigned ints?
Log: result.Log,
Data: result.Data,
Events: result.Events.ToABCIEvents(),
Events: result.Events,
}
}

Expand Down Expand Up @@ -331,15 +331,20 @@ func handleQueryApp(app *BaseApp, path []string, req abci.RequestQuery) abci.Res
return sdkerrors.QueryResult(sdkerrors.Wrap(err, "failed to simulate tx"))
}

simRes := sdk.SimulationResponse{
simRes := &sdk.SimulationResponse{
GasInfo: gInfo,
Result: res,
}

bz, err := codec.ProtoMarshalJSON(simRes)
if err != nil {
return sdkerrors.QueryResult(sdkerrors.Wrap(err, "failed to JSON encode simulation response"))
}

return abci.ResponseQuery{
Codespace: sdkerrors.RootCodespace,
Height: req.Height,
Value: codec.Cdc.MustMarshalBinaryBare(simRes),
Value: bz,
}

case "version":
Expand Down
4 changes: 2 additions & 2 deletions baseapp/baseapp.go
Original file line number Diff line number Diff line change
Expand Up @@ -606,7 +606,7 @@ func (app *BaseApp) runMsgs(ctx sdk.Context, msgs []sdk.Msg, mode runTxMode) (*s
msgEvents := sdk.Events{
sdk.NewEvent(sdk.EventTypeMessage, sdk.NewAttribute(sdk.AttributeKeyAction, msg.Type())),
}
msgEvents = msgEvents.AppendEvents(msgResult.Events)
msgEvents = msgEvents.AppendEvents(msgResult.GetEvents())

// append message events, data and logs
//
Expand All @@ -620,6 +620,6 @@ func (app *BaseApp) runMsgs(ctx sdk.Context, msgs []sdk.Msg, mode runTxMode) (*s
return &sdk.Result{
Data: data,
Log: strings.TrimSpace(msgLogs.String()),
Events: events,
Events: events.ToABCIEvents(),
}, nil
}
7 changes: 5 additions & 2 deletions baseapp/baseapp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ import (
"encoding/binary"
"fmt"
"os"
"strings"
"sync"
"testing"

"github.com/gogo/protobuf/jsonpb"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

Expand Down Expand Up @@ -936,12 +938,13 @@ func TestSimulateTx(t *testing.T) {
require.True(t, queryResult.IsOK(), queryResult.Log)

var simRes sdk.SimulationResponse
err = codec.Cdc.UnmarshalBinaryBare(queryResult.Value, &simRes)
require.NoError(t, err)
require.NoError(t, jsonpb.Unmarshal(strings.NewReader(string(queryResult.Value)), &simRes))

require.Equal(t, gInfo, simRes.GasInfo)
require.Equal(t, result.Log, simRes.Result.Log)
require.Equal(t, result.Events, simRes.Result.Events)
require.True(t, bytes.Equal(result.Data, simRes.Result.Data))

app.EndBlock(abci.RequestEndBlock{})
app.Commit()
}
Expand Down
48 changes: 37 additions & 11 deletions client/context/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,12 @@ import (

"github.com/pkg/errors"
"github.com/spf13/viper"
yaml "gopkg.in/yaml.v2"

"github.com/tendermint/tendermint/libs/cli"
tmlite "github.com/tendermint/tendermint/lite"
rpcclient "github.com/tendermint/tendermint/rpc/client"
yaml "gopkg.in/yaml.v2"

"github.com/cosmos/cosmos-sdk/client/flags"
clientx "github.com/cosmos/cosmos-sdk/client/tx"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
sdk "github.com/cosmos/cosmos-sdk/types"
Expand All @@ -26,7 +24,6 @@ type CLIContext struct {
FromAddress sdk.AccAddress
Client rpcclient.Client
ChainID string
TxGenerator clientx.Generator
Marshaler codec.Marshaler
Keybase keyring.Keybase
Input io.Reader
Expand Down Expand Up @@ -138,12 +135,6 @@ func (ctx CLIContext) WithInput(r io.Reader) CLIContext {
return ctx
}

// WithTxGenerator returns a copy of the CLIContext with an updated TxGenerator.
func (ctx CLIContext) WithTxGenerator(txg clientx.Generator) CLIContext {
ctx.TxGenerator = txg
return ctx
}

// WithMarshaler returns a copy of the CLIContext with an updated Marshaler.
func (ctx CLIContext) WithMarshaler(m codec.Marshaler) CLIContext {
ctx.Marshaler = m
Expand Down Expand Up @@ -249,9 +240,44 @@ func (ctx CLIContext) WithBroadcastMode(mode string) CLIContext {
return ctx
}

// Println outputs toPrint to the ctx.Output based on ctx.OutputFormat which is
// either text or json. If text, toPrint will be YAML encoded. Otherwise, toPrint
// will be JSON encoded using ctx.Marshaler. An error is returned upon failure.
func (ctx CLIContext) Println(toPrint interface{}) error {
var (
out []byte
err error
)

switch ctx.OutputFormat {
case "text":
out, err = yaml.Marshal(&toPrint)

case "json":
out, err = ctx.Marshaler.MarshalJSON(toPrint)

// To JSON indent, we re-encode the already encoded JSON given there is no
// error. The re-encoded JSON uses the standard library as the initial encoded
// JSON should have the correct output produced by ctx.Marshaler.
if ctx.Indent && err == nil {
out, err = codec.MarshalIndentFromJSON(out)
}
}

if err != nil {
return err
}

_, err = fmt.Fprintf(ctx.Output, "%s\n", out)
return err
}

// PrintOutput prints output while respecting output and indent flags
// NOTE: pass in marshalled structs that have been unmarshaled
// because this function will panic on marshaling errors
// because this function will panic on marshaling errors.
//
// TODO: Remove once client-side Protobuf migration has been completed.
// ref: https://github.com/cosmos/cosmos-sdk/issues/5864
func (ctx CLIContext) PrintOutput(toPrint interface{}) error {
var (
out []byte
Expand Down
163 changes: 163 additions & 0 deletions client/tx/factory.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
package tx

import (
"io"

"github.com/spf13/viper"

"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
sdk "github.com/cosmos/cosmos-sdk/types"
)

// AccountRetriever defines the interfaces required for use by the Factory to
// ensure an account exists and to be able to query for account fields necessary
// for signing.
type AccountRetriever interface {
EnsureExists(addr sdk.AccAddress) error
GetAccountNumberSequence(addr sdk.AccAddress) (uint64, uint64, error)
}

// Factory defines a client transaction factory that facilitates generating and
// signing an application-specific transaction.
type Factory struct {
keybase keyring.Keybase
txGenerator Generator
accountRetriever AccountRetriever
accountNumber uint64
sequence uint64
gas uint64
gasAdjustment float64
simulateAndExecute bool
chainID string
memo string
fees sdk.Coins
gasPrices sdk.DecCoins
}

func NewFactoryFromCLI(input io.Reader) Factory {
kb, err := keyring.NewKeyring(
sdk.KeyringServiceName(),
viper.GetString(flags.FlagKeyringBackend),
viper.GetString(flags.FlagHome),
input,
)
if err != nil {
panic(err)
}

f := Factory{
keybase: kb,
accountNumber: viper.GetUint64(flags.FlagAccountNumber),
sequence: viper.GetUint64(flags.FlagSequence),
gas: flags.GasFlagVar.Gas,
gasAdjustment: viper.GetFloat64(flags.FlagGasAdjustment),
simulateAndExecute: flags.GasFlagVar.Simulate,
chainID: viper.GetString(flags.FlagChainID),
memo: viper.GetString(flags.FlagMemo),
}

f = f.WithFees(viper.GetString(flags.FlagFees))
f = f.WithGasPrices(viper.GetString(flags.FlagGasPrices))

return f
}

// nolint
func (f Factory) AccountNumber() uint64 { return f.accountNumber }
func (f Factory) Sequence() uint64 { return f.sequence }
func (f Factory) Gas() uint64 { return f.gas }
func (f Factory) GasAdjustment() float64 { return f.gasAdjustment }
func (f Factory) Keybase() keyring.Keybase { return f.keybase }
func (f Factory) ChainID() string { return f.chainID }
func (f Factory) Memo() string { return f.memo }
func (f Factory) Fees() sdk.Coins { return f.fees }
func (f Factory) GasPrices() sdk.DecCoins { return f.gasPrices }
func (f Factory) AccountRetriever() AccountRetriever { return f.accountRetriever }

// SimulateAndExecute returns the option to simulate and then execute the transaction
// using the gas from the simulation results
func (f Factory) SimulateAndExecute() bool { return f.simulateAndExecute }

// WithTxGenerator returns a copy of the Factory with an updated Generator.
func (f Factory) WithTxGenerator(g Generator) Factory {
f.txGenerator = g
return f
}

// WithAccountRetriever returns a copy of the Factory with an updated AccountRetriever.
func (f Factory) WithAccountRetriever(ar AccountRetriever) Factory {
f.accountRetriever = ar
return f
}

// WithChainID returns a copy of the Factory with an updated chainID.
func (f Factory) WithChainID(chainID string) Factory {
f.chainID = chainID
return f
}

// WithGas returns a copy of the Factory with an updated gas value.
func (f Factory) WithGas(gas uint64) Factory {
f.gas = gas
return f
}

// WithFees returns a copy of the Factory with an updated fee.
func (f Factory) WithFees(fees string) Factory {
parsedFees, err := sdk.ParseCoins(fees)
if err != nil {
panic(err)
}

f.fees = parsedFees
return f
}

// WithGasPrices returns a copy of the Factory with updated gas prices.
func (f Factory) WithGasPrices(gasPrices string) Factory {
parsedGasPrices, err := sdk.ParseDecCoins(gasPrices)
if err != nil {
panic(err)
}

f.gasPrices = parsedGasPrices
return f
}

// WithKeybase returns a copy of the Factory with updated Keybase.
func (f Factory) WithKeybase(keybase keyring.Keybase) Factory {
f.keybase = keybase
return f
}

// WithSequence returns a copy of the Factory with an updated sequence number.
func (f Factory) WithSequence(sequence uint64) Factory {
f.sequence = sequence
return f
}

// WithMemo returns a copy of the Factory with an updated memo.
func (f Factory) WithMemo(memo string) Factory {
f.memo = memo
return f
}

// WithAccountNumber returns a copy of the Factory with an updated account number.
func (f Factory) WithAccountNumber(accnum uint64) Factory {
f.accountNumber = accnum
return f
}

// WithGasAdjustment returns a copy of the Factory with an updated gas adjustment.
func (f Factory) WithGasAdjustment(gasAdj float64) Factory {
f.gasAdjustment = gasAdj
return f
}

// WithSimulateAndExecute returns a copy of the Factory with an updated gas
// simulation value.
func (f Factory) WithSimulateAndExecute(sim bool) Factory {
f.simulateAndExecute = sim
return f
}
Loading

0 comments on commit 6a9c8bc

Please sign in to comment.