Migrate x/genutil to use TxConfig (#6734)

* Update genutil collect and gentx to use TxGenerator

* Remove print statement

* Use Tx in genutil DeliverGenTxs

* Use Tx in genutil genesis_state

* Use Tx in ValidateGenesis

* Use amino txJSONDecoder and txBinaryEncoder in genutil InitGenesis

* Use TxConfig in place of TxGenerator

* Add gentx tests

* Remove commented line

* Test fixes

* Apply suggestions from code review

Co-authored-by: Alexander Bezobchuk <alexanderbez@users.noreply.github.com>

* Fixes

* Fixes

* Fixes

* Fixes

* Remove unneeded test case (doesn't apply to proto marshaling)

* linting

* Refactor to use new TxEncodingConfig interface in genutil module

* Replace golang/protobuf with gogo/protobuf package

* Use TxEncodingConfig in InitTestnet

* Remove old amino.go file

* Use TxJSONDecoder in genutil ValidateGenesis

* Add parameter to ValidateGenesis to resolve the tx JSON decoder issue

* Address review feedback

Co-authored-by: Jack Zampolin <jack.zampolin@gmail.com>
Co-authored-by: Aaron Craelius <aaronc@users.noreply.github.com>
Co-authored-by: Aaron Craelius <aaron@regen.network>
Co-authored-by: Alexander Bezobchuk <alexanderbez@users.noreply.github.com>
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
This commit is contained in:
Marie 2020-07-25 10:10:04 +02:00 committed by GitHub
parent 3bafd8255a
commit f59df68a97
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
40 changed files with 488 additions and 163 deletions

View File

@ -152,6 +152,7 @@ be used to retrieve the actual proposal `Content`. Also the `NewMsgSubmitProposa
* (client/flags) [\#6632](https://github.com/cosmos/cosmos-sdk/pull/6632) Remove NewCompletionCmd(), the function is now available in tendermint.
* (crypto) [\#6780](https://github.com/cosmos/cosmos-sdk/issues/6780) Move ledger code to its own package.
* (modules) [\#6834](https://github.com/cosmos/cosmos-sdk/issues/6834) Add `RegisterInterfaces` method to `AppModuleBasic` to support registration of protobuf interface types.
* (modules) [\#6734](https://github.com/cosmos/cosmos-sdk/issues/6834) Add `TxEncodingConfig` parameter to `AppModuleBasic.ValidateGenesis` command to support JSON tx decoding in `genutil`.
### Features

View File

@ -7,20 +7,26 @@ import (
)
type (
// TxConfig defines an interface a client can utilize to generate an
// application-defined concrete transaction type. The type returned must
// implement TxBuilder.
TxConfig interface {
NewTxBuilder() TxBuilder
WrapTxBuilder(sdk.Tx) (TxBuilder, error)
SignModeHandler() signing.SignModeHandler
// TxEncodingConfig defines an interface that contains transaction
// encoders and decoders
TxEncodingConfig interface {
TxEncoder() sdk.TxEncoder
TxDecoder() sdk.TxDecoder
TxJSONEncoder() sdk.TxEncoder
TxJSONDecoder() sdk.TxDecoder
}
// TxConfig defines an interface a client can utilize to generate an
// application-defined concrete transaction type. The type returned must
// implement TxBuilder.
TxConfig interface {
TxEncodingConfig
NewTxBuilder() TxBuilder
WrapTxBuilder(sdk.Tx) (TxBuilder, error)
SignModeHandler() signing.SignModeHandler
}
// TxBuilder defines an interface which an application-defined concrete transaction
// type must implement. Namely, it must be able to set messages, generate
// signatures, and provide canonical bytes to sign over. The transaction must

View File

@ -289,7 +289,10 @@ func NewSimApp(
// NOTE: Any module instantiated in the module manager that is later modified
// must be passed by reference here.
app.mm = module.NewManager(
genutil.NewAppModule(app.AccountKeeper, app.StakingKeeper, app.BaseApp.DeliverTx),
genutil.NewAppModule(
app.AccountKeeper, app.StakingKeeper, app.BaseApp.DeliverTx,
encodingConfig.TxConfig,
),
auth.NewAppModule(appCodec, app.AccountKeeper),
bank.NewAppModule(appCodec, app.BankKeeper, app.AccountKeeper),
capability.NewAppModule(appCodec, *app.CapabilityKeeper),

View File

@ -15,7 +15,7 @@ func MakeEncodingConfig() EncodingConfig {
cdc := codec.New()
interfaceRegistry := types.NewInterfaceRegistry()
marshaler := codec.NewHybridCodec(cdc, interfaceRegistry)
txGen := tx.NewTxConfig(marshaler, std.DefaultPublicKeyCodec{}, tx.DefaultSignModeHandler())
txGen := tx.NewTxConfig(interfaceRegistry, std.DefaultPublicKeyCodec{}, tx.DefaultSignModeHandler())
return EncodingConfig{
InterfaceRegistry: interfaceRegistry,

View File

@ -78,8 +78,8 @@ func init() {
genutilcli.InitCmd(simapp.ModuleBasics, simapp.DefaultNodeHome),
genutilcli.CollectGenTxsCmd(banktypes.GenesisBalancesIterator{}, simapp.DefaultNodeHome),
genutilcli.MigrateGenesisCmd(),
genutilcli.GenTxCmd(simapp.ModuleBasics, banktypes.GenesisBalancesIterator{}, simapp.DefaultNodeHome),
genutilcli.ValidateGenesisCmd(simapp.ModuleBasics),
genutilcli.GenTxCmd(simapp.ModuleBasics, encodingConfig.TxConfig, banktypes.GenesisBalancesIterator{}, simapp.DefaultNodeHome),
genutilcli.ValidateGenesisCmd(simapp.ModuleBasics, encodingConfig.TxConfig),
AddGenesisAccountCmd(simapp.DefaultNodeHome),
cli.NewCompletionCmd(rootCmd, true),
testnetCmd(simapp.ModuleBasics, banktypes.GenesisBalancesIterator{}),

View File

@ -74,7 +74,7 @@ Example:
numValidators, _ := cmd.Flags().GetInt(flagNumValidators)
return InitTestnet(
cmd, config, cdc, mbm, genBalIterator, outputDir, chainID, minGasPrices,
cmd, config, cdc, clientCtx.TxConfig, mbm, genBalIterator, outputDir, chainID, minGasPrices,
nodeDirPrefix, nodeDaemonHome, nodeCLIHome, startingIPAddress, keyringBackend, numValidators,
)
},
@ -97,7 +97,8 @@ const nodeDirPerm = 0755
// Initialize the testnet
func InitTestnet(
cmd *cobra.Command, config *tmconfig.Config, cdc codec.JSONMarshaler,
cmd *cobra.Command, nodeConfig *tmconfig.Config, cdc codec.JSONMarshaler,
txEncodingConfig client.TxEncodingConfig,
mbm module.BasicManager, genBalIterator banktypes.GenesisBalancesIterator,
outputDir, chainID, minGasPrices, nodeDirPrefix, nodeDaemonHome,
nodeCLIHome, startingIPAddress, keyringBackend string, numValidators int,
@ -132,8 +133,8 @@ func InitTestnet(
clientDir := filepath.Join(outputDir, nodeDirName, nodeCLIHome)
gentxsDir := filepath.Join(outputDir, "gentxs")
config.SetRoot(nodeDir)
config.RPC.ListenAddress = "tcp://0.0.0.0:26657"
nodeConfig.SetRoot(nodeDir)
nodeConfig.RPC.ListenAddress = "tcp://0.0.0.0:26657"
if err := os.MkdirAll(filepath.Join(nodeDir, "config"), nodeDirPerm); err != nil {
_ = os.RemoveAll(outputDir)
@ -145,7 +146,7 @@ func InitTestnet(
return err
}
config.Moniker = nodeDirName
nodeConfig.Moniker = nodeDirName
ip, err := getIP(i, startingIPAddress)
if err != nil {
@ -153,14 +154,14 @@ func InitTestnet(
return err
}
nodeIDs[i], valPubKeys[i], err = genutil.InitializeNodeValidatorFiles(config)
nodeIDs[i], valPubKeys[i], err = genutil.InitializeNodeValidatorFiles(nodeConfig)
if err != nil {
_ = os.RemoveAll(outputDir)
return err
}
memo := fmt.Sprintf("%s@%s:26656", nodeIDs[i], ip)
genFiles = append(genFiles, config.GenesisFile())
genFiles = append(genFiles, nodeConfig.GenesisFile())
kb, err := keyring.New(sdk.KeyringServiceName(), keyringBackend, clientDir, inBuf)
if err != nil {
@ -240,7 +241,7 @@ func InitTestnet(
}
err := collectGenFiles(
cdc, config, chainID, nodeIDs, valPubKeys, numValidators,
cdc, txEncodingConfig, nodeConfig, chainID, nodeIDs, valPubKeys, numValidators,
outputDir, nodeDirPrefix, nodeDaemonHome, genBalIterator,
)
if err != nil {
@ -294,7 +295,8 @@ func initGenFiles(
}
func collectGenFiles(
cdc codec.JSONMarshaler, config *tmconfig.Config, chainID string,
cdc codec.JSONMarshaler, txEncodingConfig client.TxEncodingConfig,
nodeConfig *tmconfig.Config, chainID string,
nodeIDs []string, valPubKeys []crypto.PubKey,
numValidators int, outputDir, nodeDirPrefix, nodeDaemonHome string,
genBalIterator banktypes.GenesisBalancesIterator,
@ -307,19 +309,19 @@ func collectGenFiles(
nodeDirName := fmt.Sprintf("%s%d", nodeDirPrefix, i)
nodeDir := filepath.Join(outputDir, nodeDirName, nodeDaemonHome)
gentxsDir := filepath.Join(outputDir, "gentxs")
config.Moniker = nodeDirName
nodeConfig.Moniker = nodeDirName
config.SetRoot(nodeDir)
nodeConfig.SetRoot(nodeDir)
nodeID, valPubKey := nodeIDs[i], valPubKeys[i]
initCfg := genutiltypes.NewInitConfig(chainID, gentxsDir, nodeID, valPubKey)
genDoc, err := types.GenesisDocFromFile(config.GenesisFile())
genDoc, err := types.GenesisDocFromFile(nodeConfig.GenesisFile())
if err != nil {
return err
}
nodeAppState, err := genutil.GenAppStateFromConfig(cdc, config, initCfg, *genDoc, genBalIterator)
nodeAppState, err := genutil.GenAppStateFromConfig(cdc, txEncodingConfig, nodeConfig, initCfg, *genDoc, genBalIterator)
if err != nil {
return err
}
@ -329,7 +331,7 @@ func collectGenFiles(
appState = nodeAppState
}
genFile := config.GenesisFile()
genFile := nodeConfig.GenesisFile()
// overwrite each validator's genesis file to have a canonical genesis time
if err := genutil.ExportGenesisFileWithTime(genFile, chainID, nil, appState, genTime); err != nil {

View File

@ -95,17 +95,17 @@ func (mr *MockAppModuleBasicMockRecorder) DefaultGenesis(arg0 interface{}) *gomo
}
// ValidateGenesis mocks base method
func (m *MockAppModuleBasic) ValidateGenesis(arg0 codec.JSONMarshaler, arg1 json.RawMessage) error {
func (m *MockAppModuleBasic) ValidateGenesis(arg0 codec.JSONMarshaler, arg1 client.TxEncodingConfig, arg2 json.RawMessage) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ValidateGenesis", arg0, arg1)
ret := m.ctrl.Call(m, "ValidateGenesis", arg0, arg1, arg2)
ret0, _ := ret[0].(error)
return ret0
}
// ValidateGenesis indicates an expected call of ValidateGenesis
func (mr *MockAppModuleBasicMockRecorder) ValidateGenesis(arg0, arg1 interface{}) *gomock.Call {
func (mr *MockAppModuleBasicMockRecorder) ValidateGenesis(arg0, arg1, arg2 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidateGenesis", reflect.TypeOf((*MockAppModuleBasic)(nil).ValidateGenesis), arg0, arg1)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidateGenesis", reflect.TypeOf((*MockAppModuleBasic)(nil).ValidateGenesis), arg0, arg1, arg2)
}
// RegisterRESTRoutes mocks base method
@ -224,17 +224,17 @@ func (mr *MockAppModuleGenesisMockRecorder) DefaultGenesis(arg0 interface{}) *go
}
// ValidateGenesis mocks base method
func (m *MockAppModuleGenesis) ValidateGenesis(arg0 codec.JSONMarshaler, arg1 json.RawMessage) error {
func (m *MockAppModuleGenesis) ValidateGenesis(arg0 codec.JSONMarshaler, arg1 client.TxEncodingConfig, arg2 json.RawMessage) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ValidateGenesis", arg0, arg1)
ret := m.ctrl.Call(m, "ValidateGenesis", arg0, arg1, arg2)
ret0, _ := ret[0].(error)
return ret0
}
// ValidateGenesis indicates an expected call of ValidateGenesis
func (mr *MockAppModuleGenesisMockRecorder) ValidateGenesis(arg0, arg1 interface{}) *gomock.Call {
func (mr *MockAppModuleGenesisMockRecorder) ValidateGenesis(arg0, arg1, arg2 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidateGenesis", reflect.TypeOf((*MockAppModuleGenesis)(nil).ValidateGenesis), arg0, arg1)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidateGenesis", reflect.TypeOf((*MockAppModuleGenesis)(nil).ValidateGenesis), arg0, arg1, arg2)
}
// RegisterRESTRoutes mocks base method
@ -381,17 +381,17 @@ func (mr *MockAppModuleMockRecorder) DefaultGenesis(arg0 interface{}) *gomock.Ca
}
// ValidateGenesis mocks base method
func (m *MockAppModule) ValidateGenesis(arg0 codec.JSONMarshaler, arg1 json.RawMessage) error {
func (m *MockAppModule) ValidateGenesis(arg0 codec.JSONMarshaler, arg1 client.TxEncodingConfig, arg2 json.RawMessage) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ValidateGenesis", arg0, arg1)
ret := m.ctrl.Call(m, "ValidateGenesis", arg0, arg1, arg2)
ret0, _ := ret[0].(error)
return ret0
}
// ValidateGenesis indicates an expected call of ValidateGenesis
func (mr *MockAppModuleMockRecorder) ValidateGenesis(arg0, arg1 interface{}) *gomock.Call {
func (mr *MockAppModuleMockRecorder) ValidateGenesis(arg0, arg1, arg2 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidateGenesis", reflect.TypeOf((*MockAppModule)(nil).ValidateGenesis), arg0, arg1)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidateGenesis", reflect.TypeOf((*MockAppModule)(nil).ValidateGenesis), arg0, arg1, arg2)
}
// RegisterRESTRoutes mocks base method

View File

@ -13,6 +13,8 @@ import (
"testing"
"time"
"github.com/cosmos/cosmos-sdk/client/tx"
"github.com/stretchr/testify/require"
tmcfg "github.com/tendermint/tendermint/config"
"github.com/tendermint/tendermint/crypto"
@ -278,16 +280,21 @@ func New(t *testing.T, cfg Config) *Network {
require.NoError(t, err)
memo := fmt.Sprintf("%s@%s:%s", nodeIDs[i], p2pURL.Hostname(), p2pURL.Port())
tx := authtypes.NewStdTx([]sdk.Msg{createValMsg}, authtypes.StdFee{}, []authtypes.StdSignature{}, memo) //nolint:staticcheck // SA1019: authtypes.StdFee is deprecated
txBldr := authtypes.TxBuilder{}.
txBuilder := cfg.TxConfig.NewTxBuilder()
require.NoError(t, txBuilder.SetMsgs(createValMsg))
txBuilder.SetMemo(memo)
txFactory := tx.Factory{}
txFactory = txFactory.
WithChainID(cfg.ChainID).
WithMemo(memo).
WithKeybase(kb)
WithKeybase(kb).
WithTxConfig(cfg.TxConfig)
signedTx, err := txBldr.SignStdTx(nodeDirName, tx, false)
err = tx.Sign(txFactory, nodeDirName, txBuilder)
require.NoError(t, err)
txBz, err := cfg.Codec.MarshalJSON(signedTx)
txBz, err := cfg.TxConfig.TxJSONEncoder()(txBuilder.GetTx())
require.NoError(t, err)
require.NoError(t, writeFile(fmt.Sprintf("%v.json", nodeDirName), gentxsDir, txBz))

View File

@ -105,7 +105,8 @@ func collectGenFiles(cfg Config, vals []*Validator, outputDir string) error {
return err
}
appState, err := genutil.GenAppStateFromConfig(cfg.Codec, tmCfg, initCfg, *genDoc, banktypes.GenesisBalancesIterator{})
appState, err := genutil.GenAppStateFromConfig(cfg.Codec, cfg.TxConfig,
tmCfg, initCfg, *genDoc, banktypes.GenesisBalancesIterator{})
if err != nil {
return err
}

View File

@ -52,7 +52,7 @@ type AppModuleBasic interface {
RegisterInterfaces(codectypes.InterfaceRegistry)
DefaultGenesis(codec.JSONMarshaler) json.RawMessage
ValidateGenesis(codec.JSONMarshaler, json.RawMessage) error
ValidateGenesis(codec.JSONMarshaler, client.TxEncodingConfig, json.RawMessage) error
// client functionality
RegisterRESTRoutes(client.Context, *mux.Router)
@ -97,9 +97,9 @@ func (bm BasicManager) DefaultGenesis(cdc codec.JSONMarshaler) map[string]json.R
}
// ValidateGenesis performs genesis state validation for all modules
func (bm BasicManager) ValidateGenesis(cdc codec.JSONMarshaler, genesis map[string]json.RawMessage) error {
func (bm BasicManager) ValidateGenesis(cdc codec.JSONMarshaler, txEncCfg client.TxEncodingConfig, genesis map[string]json.RawMessage) error {
for _, b := range bm {
if err := b.ValidateGenesis(cdc, genesis[b.Name()]); err != nil {
if err := b.ValidateGenesis(cdc, txEncCfg, genesis[b.Name()]); err != nil {
return err
}
}

View File

@ -35,7 +35,7 @@ func TestBasicManager(t *testing.T) {
mockAppModuleBasic1.EXPECT().Name().AnyTimes().Return("mockAppModuleBasic1")
mockAppModuleBasic1.EXPECT().DefaultGenesis(gomock.Eq(cdc)).Times(1).Return(json.RawMessage(``))
mockAppModuleBasic1.EXPECT().ValidateGenesis(gomock.Eq(cdc), gomock.Eq(wantDefaultGenesis["mockAppModuleBasic1"])).Times(1).Return(errFoo)
mockAppModuleBasic1.EXPECT().ValidateGenesis(gomock.Eq(cdc), gomock.Eq(nil), gomock.Eq(wantDefaultGenesis["mockAppModuleBasic1"])).Times(1).Return(errFoo)
mockAppModuleBasic1.EXPECT().RegisterRESTRoutes(gomock.Eq(client.Context{}), gomock.Eq(&mux.Router{})).Times(1)
mockAppModuleBasic1.EXPECT().RegisterCodec(gomock.Eq(cdc)).Times(1)
mockAppModuleBasic1.EXPECT().RegisterInterfaces(gomock.Eq(interfaceRegistry)).Times(1)
@ -53,7 +53,7 @@ func TestBasicManager(t *testing.T) {
var data map[string]string
require.Equal(t, map[string]string(nil), data)
require.True(t, errors.Is(errFoo, mm.ValidateGenesis(cdc, wantDefaultGenesis)))
require.True(t, errors.Is(errFoo, mm.ValidateGenesis(cdc, nil, wantDefaultGenesis)))
mm.RegisterRESTRoutes(client.Context{}, &mux.Router{})
@ -63,7 +63,7 @@ func TestBasicManager(t *testing.T) {
mm.AddQueryCommands(mockCmd)
// validate genesis returns nil
require.Nil(t, module.NewBasicManager().ValidateGenesis(cdc, wantDefaultGenesis))
require.Nil(t, module.NewBasicManager().ValidateGenesis(cdc, nil, wantDefaultGenesis))
}
func TestGenesisOnlyAppModule(t *testing.T) {

View File

@ -50,7 +50,7 @@ func (AppModuleBasic) DefaultGenesis(cdc codec.JSONMarshaler) json.RawMessage {
}
// ValidateGenesis performs genesis state validation for the auth module.
func (AppModuleBasic) ValidateGenesis(cdc codec.JSONMarshaler, bz json.RawMessage) error {
func (AppModuleBasic) ValidateGenesis(cdc codec.JSONMarshaler, config client.TxEncodingConfig, bz json.RawMessage) error {
var data types.GenesisState
if err := cdc.UnmarshalJSON(bz, &data); err != nil {
return fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err)

View File

@ -3,6 +3,8 @@ package tx
import (
"fmt"
"github.com/gogo/protobuf/proto"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/x/auth/signing/direct"
@ -16,7 +18,6 @@ import (
"github.com/tendermint/tendermint/crypto"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/crypto/types"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
@ -37,7 +38,6 @@ type builder struct {
// or decoded from AuthInfo when GetPubKey's was called
pubKeys []crypto.PubKey
marshaler codec.Marshaler
pubkeyCodec types.PublicKeyCodec
}
@ -47,7 +47,7 @@ var (
_ direct.ProtoTx = &builder{}
)
func newBuilder(marshaler codec.Marshaler, pubkeyCodec types.PublicKeyCodec) *builder {
func newBuilder(pubkeyCodec types.PublicKeyCodec) *builder {
return &builder{
tx: &tx.Tx{
Body: &tx.TxBody{},
@ -55,7 +55,6 @@ func newBuilder(marshaler codec.Marshaler, pubkeyCodec types.PublicKeyCodec) *bu
Fee: &tx.Fee{},
},
},
marshaler: marshaler,
pubkeyCodec: pubkeyCodec,
}
}
@ -131,7 +130,11 @@ func (t *builder) GetBodyBytes() []byte {
// this method should always return the correct bytes. Note that after
// decoding bodyBz is derived from TxRaw so that it matches what was
// transmitted over the wire
t.bodyBz = t.marshaler.MustMarshalBinaryBare(t.tx.Body)
var err error
t.bodyBz, err = proto.Marshal(t.tx.Body)
if err != nil {
panic(err)
}
}
return t.bodyBz
}
@ -143,7 +146,11 @@ func (t *builder) GetAuthInfoBytes() []byte {
// this method should always return the correct bytes. Note that after
// decoding authInfoBz is derived from TxRaw so that it matches what was
// transmitted over the wire
t.authInfoBz = t.marshaler.MustMarshalBinaryBare(t.tx.AuthInfo)
var err error
t.authInfoBz, err = proto.Marshal(t.tx.AuthInfo)
if err != nil {
panic(err)
}
}
return t.authInfoBz
}

View File

@ -22,7 +22,7 @@ func TestTxBuilder(t *testing.T) {
_, pubkey, addr := testdata.KeyTestPubAddr()
marshaler := codec.NewHybridCodec(codec.New(), codectypes.NewInterfaceRegistry())
tx := newBuilder(marshaler, std.DefaultPublicKeyCodec{})
tx := newBuilder(std.DefaultPublicKeyCodec{})
cdc := std.DefaultPublicKeyCodec{}
@ -125,8 +125,7 @@ func TestBuilderValidateBasic(t *testing.T) {
// require to fail validation upon invalid fee
badFeeAmount := testdata.NewTestFeeAmount()
badFeeAmount[0].Amount = sdk.NewInt(-5)
marshaler := codec.NewHybridCodec(codec.New(), codectypes.NewInterfaceRegistry())
bldr := newBuilder(marshaler, std.DefaultPublicKeyCodec{})
bldr := newBuilder(std.DefaultPublicKeyCodec{})
var sig1, sig2 signing.SignatureV2
sig1 = signing.SignatureV2{

View File

@ -3,15 +3,18 @@ package tx
import (
"github.com/tendermint/tendermint/crypto"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/types/tx"
"github.com/cosmos/cosmos-sdk/codec"
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
sdk "github.com/cosmos/cosmos-sdk/types"
)
// DefaultTxDecoder returns a default protobuf TxDecoder using the provided Marshaler and PublicKeyCodec
func DefaultTxDecoder(cdc codec.Marshaler, keyCodec cryptotypes.PublicKeyCodec) sdk.TxDecoder {
func DefaultTxDecoder(anyUnpacker types.AnyUnpacker, keyCodec cryptotypes.PublicKeyCodec) sdk.TxDecoder {
cdc := codec.NewProtoCodec(anyUnpacker)
return func(txBytes []byte) (sdk.Tx, error) {
var raw tx.TxRaw
err := cdc.UnmarshalBinaryBare(txBytes, &raw)
@ -35,14 +38,14 @@ func DefaultTxDecoder(cdc codec.Marshaler, keyCodec cryptotypes.PublicKeyCodec)
bodyBz: raw.BodyBytes,
authInfoBz: raw.AuthInfoBytes,
pubKeys: pks,
marshaler: cdc,
pubkeyCodec: keyCodec,
}, nil
}
}
// DefaultTxDecoder returns a default protobuf JSON TxDecoder using the provided Marshaler and PublicKeyCodec
func DefaultJSONTxDecoder(cdc codec.Marshaler, keyCodec cryptotypes.PublicKeyCodec) sdk.TxDecoder {
func DefaultJSONTxDecoder(anyUnpacker types.AnyUnpacker, keyCodec cryptotypes.PublicKeyCodec) sdk.TxDecoder {
cdc := codec.NewProtoCodec(anyUnpacker)
return func(txBytes []byte) (sdk.Tx, error) {
var theTx tx.Tx
err := cdc.UnmarshalJSON(txBytes, &theTx)
@ -58,7 +61,6 @@ func DefaultJSONTxDecoder(cdc codec.Marshaler, keyCodec cryptotypes.PublicKeyCod
return &builder{
tx: &theTx,
pubKeys: pks,
marshaler: cdc,
pubkeyCodec: keyCodec,
}, nil
}

View File

@ -3,13 +3,15 @@ package tx
import (
"fmt"
"github.com/gogo/protobuf/proto"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/types"
txtypes "github.com/cosmos/cosmos-sdk/types/tx"
)
// DefaultTxEncoder returns a default protobuf TxEncoder using the provided Marshaler
func DefaultTxEncoder(marshaler codec.Marshaler) types.TxEncoder {
func DefaultTxEncoder() types.TxEncoder {
return func(tx types.Tx) ([]byte, error) {
wrapper, ok := tx.(*builder)
if !ok {
@ -22,18 +24,18 @@ func DefaultTxEncoder(marshaler codec.Marshaler) types.TxEncoder {
Signatures: wrapper.tx.Signatures,
}
return marshaler.MarshalBinaryBare(raw)
return proto.Marshal(raw)
}
}
// DefaultTxEncoder returns a default protobuf JSON TxEncoder using the provided Marshaler
func DefaultJSONTxEncoder(marshaler codec.Marshaler) types.TxEncoder {
func DefaultJSONTxEncoder() types.TxEncoder {
return func(tx types.Tx) ([]byte, error) {
wrapper, ok := tx.(*builder)
if !ok {
return nil, fmt.Errorf("expected %T, got %T", &builder{}, tx)
}
return marshaler.MarshalJSON(wrapper.tx)
return codec.ProtoMarshalJSON(wrapper.tx)
}
}

View File

@ -4,14 +4,13 @@ import (
"fmt"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/codec"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/crypto/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth/signing"
)
type generator struct {
marshaler codec.Marshaler
pubkeyCodec types.PublicKeyCodec
handler signing.SignModeHandler
decoder sdk.TxDecoder
@ -21,20 +20,19 @@ type generator struct {
}
// NewTxConfig returns a new protobuf TxConfig using the provided Marshaler, PublicKeyCodec and SignModeHandler.
func NewTxConfig(marshaler codec.Marshaler, pubkeyCodec types.PublicKeyCodec, signModeHandler signing.SignModeHandler) client.TxConfig {
func NewTxConfig(anyUnpacker codectypes.AnyUnpacker, pubkeyCodec types.PublicKeyCodec, signModeHandler signing.SignModeHandler) client.TxConfig {
return &generator{
marshaler: marshaler,
pubkeyCodec: pubkeyCodec,
handler: signModeHandler,
decoder: DefaultTxDecoder(marshaler, pubkeyCodec),
encoder: DefaultTxEncoder(marshaler),
jsonDecoder: DefaultJSONTxDecoder(marshaler, pubkeyCodec),
jsonEncoder: DefaultJSONTxEncoder(marshaler),
decoder: DefaultTxDecoder(anyUnpacker, pubkeyCodec),
encoder: DefaultTxEncoder(),
jsonDecoder: DefaultJSONTxDecoder(anyUnpacker, pubkeyCodec),
jsonEncoder: DefaultJSONTxEncoder(),
}
}
func (g generator) NewTxBuilder() client.TxBuilder {
return newBuilder(g.marshaler, g.pubkeyCodec)
return newBuilder(g.pubkeyCodec)
}
// WrapTxBuilder returns a builder from provided transaction

View File

@ -47,7 +47,7 @@ func (AppModuleBasic) DefaultGenesis(cdc codec.JSONMarshaler) json.RawMessage {
}
// ValidateGenesis performs genesis state validation for the bank module.
func (AppModuleBasic) ValidateGenesis(cdc codec.JSONMarshaler, bz json.RawMessage) error {
func (AppModuleBasic) ValidateGenesis(cdc codec.JSONMarshaler, config client.TxEncodingConfig, bz json.RawMessage) error {
var data types.GenesisState
if err := cdc.UnmarshalJSON(bz, &data); err != nil {
return fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err)
@ -126,6 +126,7 @@ func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc codec.JSONMarshaler) s
// no validator updates.
func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONMarshaler, data json.RawMessage) []abci.ValidatorUpdate {
var genesisState types.GenesisState
cdc.MustUnmarshalJSON(data, &genesisState)
am.keeper.InitGenesis(ctx, genesisState)
return []abci.ValidatorUpdate{}

View File

@ -60,7 +60,7 @@ func (AppModuleBasic) DefaultGenesis(cdc codec.JSONMarshaler) json.RawMessage {
}
// ValidateGenesis performs genesis state validation for the capability module.
func (AppModuleBasic) ValidateGenesis(cdc codec.JSONMarshaler, bz json.RawMessage) error {
func (AppModuleBasic) ValidateGenesis(cdc codec.JSONMarshaler, config client.TxEncodingConfig, bz json.RawMessage) error {
var genState types.GenesisState
if err := cdc.UnmarshalJSON(bz, &genState); err != nil {
return fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err)

View File

@ -44,7 +44,7 @@ func (AppModuleBasic) DefaultGenesis(cdc codec.JSONMarshaler) json.RawMessage {
}
// ValidateGenesis performs genesis state validation for the crisis module.
func (AppModuleBasic) ValidateGenesis(cdc codec.JSONMarshaler, bz json.RawMessage) error {
func (AppModuleBasic) ValidateGenesis(cdc codec.JSONMarshaler, config client.TxEncodingConfig, bz json.RawMessage) error {
var data types.GenesisState
if err := cdc.UnmarshalJSON(bz, &data); err != nil {
return fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err)

View File

@ -53,7 +53,7 @@ func (AppModuleBasic) DefaultGenesis(cdc codec.JSONMarshaler) json.RawMessage {
}
// ValidateGenesis performs genesis state validation for the distribution module.
func (AppModuleBasic) ValidateGenesis(cdc codec.JSONMarshaler, bz json.RawMessage) error {
func (AppModuleBasic) ValidateGenesis(cdc codec.JSONMarshaler, config sdkclient.TxEncodingConfig, bz json.RawMessage) error {
var data types.GenesisState
if err := cdc.UnmarshalJSON(bz, &data); err != nil {
return fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err)

View File

@ -64,7 +64,7 @@ func (AppModuleBasic) DefaultGenesis(cdc codec.JSONMarshaler) json.RawMessage {
}
// ValidateGenesis performs genesis state validation for the evidence module.
func (AppModuleBasic) ValidateGenesis(cdc codec.JSONMarshaler, bz json.RawMessage) error {
func (AppModuleBasic) ValidateGenesis(cdc codec.JSONMarshaler, config client.TxEncodingConfig, bz json.RawMessage) error {
var gs types.GenesisState
if err := cdc.UnmarshalJSON(bz, &gs); err != nil {
return fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err)

View File

@ -50,7 +50,9 @@ func CollectGenTxsCmd(genBalIterator types.GenesisBalancesIterator, defaultNodeH
toPrint := newPrintInfo(config.Moniker, genDoc.ChainID, nodeID, genTxsDir, json.RawMessage(""))
initCfg := types.NewInitConfig(genDoc.ChainID, genTxsDir, nodeID, valPubKey)
appMessage, err := genutil.GenAppStateFromConfig(cdc, config, initCfg, *genDoc, genBalIterator)
appMessage, err := genutil.GenAppStateFromConfig(cdc,
clientCtx.TxConfig,
config, initCfg, *genDoc, genBalIterator)
if err != nil {
return errors.Wrap(err, "failed to get genesis app state from config")
}

View File

@ -31,7 +31,7 @@ import (
)
// GenTxCmd builds the application's gentx command.
func GenTxCmd(mbm module.BasicManager, genBalIterator types.GenesisBalancesIterator, defaultNodeHome string) *cobra.Command {
func GenTxCmd(mbm module.BasicManager, txEncCfg client.TxEncodingConfig, genBalIterator types.GenesisBalancesIterator, defaultNodeHome string) *cobra.Command {
ipDefault, _ := server.ExternalIP()
fsCreateValidator, defaultsDesc := cli.CreateValidatorMsgFlagSet(ipDefault)
@ -93,7 +93,7 @@ $ %s gentx my-key-name --home=/path/to/home/dir --keyring-backend=os --chain-id=
return errors.Wrap(err, "failed to unmarshal genesis state")
}
if err = mbm.ValidateGenesis(cdc, genesisState); err != nil {
if err = mbm.ValidateGenesis(cdc, txEncCfg, genesisState); err != nil {
return errors.Wrap(err, "failed to validate genesis state")
}

View File

@ -14,7 +14,7 @@ import (
)
// Validate genesis command takes
func ValidateGenesisCmd(mbm module.BasicManager) *cobra.Command {
func ValidateGenesisCmd(mbm module.BasicManager, txEncCfg client.TxEncodingConfig) *cobra.Command {
return &cobra.Command{
Use: "validate-genesis [file]",
Args: cobra.RangeArgs(0, 1),
@ -45,7 +45,7 @@ func ValidateGenesisCmd(mbm module.BasicManager) *cobra.Command {
return fmt.Errorf("error unmarshalling genesis doc %s: %s", genesis, err.Error())
}
if err = mbm.ValidateGenesis(cdc, genState); err != nil {
if err = mbm.ValidateGenesis(cdc, txEncCfg, genState); err != nil {
return fmt.Errorf("error validating genesis file %s: %s", genesis, err.Error())
}

View File

@ -15,22 +15,22 @@ import (
cfg "github.com/tendermint/tendermint/config"
tmtypes "github.com/tendermint/tendermint/types"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
bankexported "github.com/cosmos/cosmos-sdk/x/bank/exported"
"github.com/cosmos/cosmos-sdk/x/genutil/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
)
// GenAppStateFromConfig gets the genesis app state from the config
func GenAppStateFromConfig(cdc codec.JSONMarshaler, config *cfg.Config,
initCfg types.InitConfig, genDoc tmtypes.GenesisDoc, genBalIterator types.GenesisBalancesIterator,
func GenAppStateFromConfig(cdc codec.JSONMarshaler, txEncodingConfig client.TxEncodingConfig,
config *cfg.Config, initCfg types.InitConfig, genDoc tmtypes.GenesisDoc, genBalIterator types.GenesisBalancesIterator,
) (appState json.RawMessage, err error) {
// process genesis transactions, else create default genesis.json
appGenTxs, persistentPeers, err := CollectStdTxs(
cdc, config.Moniker, initCfg.GenTxsDir, genDoc, genBalIterator,
appGenTxs, persistentPeers, err := CollectTxs(
cdc, txEncodingConfig.TxJSONDecoder(), config.Moniker, initCfg.GenTxsDir, genDoc, genBalIterator,
)
if err != nil {
return appState, err
@ -50,7 +50,7 @@ func GenAppStateFromConfig(cdc codec.JSONMarshaler, config *cfg.Config,
return appState, err
}
appGenesisState, err = SetGenTxsInAppGenesisState(cdc, appGenesisState, appGenTxs)
appGenesisState, err = SetGenTxsInAppGenesisState(cdc, txEncodingConfig.TxJSONEncoder(), appGenesisState, appGenTxs)
if err != nil {
return appState, err
}
@ -66,11 +66,11 @@ func GenAppStateFromConfig(cdc codec.JSONMarshaler, config *cfg.Config,
return appState, err
}
// CollectStdTxs processes and validates application's genesis StdTxs and returns
// CollectTxs processes and validates application's genesis Txs and returns
// the list of appGenTxs, and persistent peers required to generate genesis.json.
func CollectStdTxs(cdc codec.JSONMarshaler, moniker, genTxsDir string,
func CollectTxs(cdc codec.JSONMarshaler, txJSONDecoder sdk.TxDecoder, moniker, genTxsDir string,
genDoc tmtypes.GenesisDoc, genBalIterator types.GenesisBalancesIterator,
) (appGenTxs []authtypes.StdTx, persistentPeers string, err error) {
) (appGenTxs []sdk.Tx, persistentPeers string, err error) {
var fos []os.FileInfo
fos, err = ioutil.ReadDir(genTxsDir)
@ -104,30 +104,35 @@ func CollectStdTxs(cdc codec.JSONMarshaler, moniker, genTxsDir string,
continue
}
// get the genStdTx
// get the genTx
var jsonRawTx []byte
if jsonRawTx, err = ioutil.ReadFile(filename); err != nil {
return appGenTxs, persistentPeers, err
}
var genStdTx authtypes.StdTx
if err = cdc.UnmarshalJSON(jsonRawTx, &genStdTx); err != nil {
var genTx sdk.Tx
if genTx, err = txJSONDecoder(jsonRawTx); err != nil {
return appGenTxs, persistentPeers, err
}
appGenTxs = append(appGenTxs, genStdTx)
appGenTxs = append(appGenTxs, genTx)
// the memo flag is used to store
// the ip and node-id, for example this may be:
// "528fd3df22b31f4969b05652bfe8f0fe921321d5@192.168.2.37:26656"
nodeAddrIP := genStdTx.GetMemo()
memoTx, ok := genTx.(sdk.TxWithMemo)
if !ok {
return appGenTxs, persistentPeers, fmt.Errorf("expected TxWithMemo, got %T", genTx)
}
nodeAddrIP := memoTx.GetMemo()
if len(nodeAddrIP) == 0 {
return appGenTxs, persistentPeers, fmt.Errorf("failed to find node's address and IP in %s", fo.Name())
}
// genesis transactions must be single-message
msgs := genStdTx.GetMsgs()
msgs := genTx.GetMsgs()
if len(msgs) != 1 {
return appGenTxs, persistentPeers, errors.New("each genesis transaction must provide a single genesis message")
}

View File

@ -3,20 +3,21 @@ package genutil
import (
abci "github.com/tendermint/tendermint/abci/types"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/client"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/genutil/types"
)
// InitGenesis - initialize accounts and deliver genesis transactions
func InitGenesis(
ctx sdk.Context, cdc *codec.Codec, stakingKeeper types.StakingKeeper,
ctx sdk.Context, stakingKeeper types.StakingKeeper,
deliverTx deliverTxfn, genesisState types.GenesisState,
txEncodingConfig client.TxEncodingConfig,
) []abci.ValidatorUpdate {
var validators []abci.ValidatorUpdate
if len(genesisState.GenTxs) > 0 {
validators = DeliverGenTxs(ctx, cdc, genesisState.GenTxs, stakingKeeper, deliverTx)
validators = DeliverGenTxs(ctx, genesisState.GenTxs, stakingKeeper, deliverTx, txEncodingConfig)
}
return validators

View File

@ -1,16 +1,14 @@
package genutil
// DONTCOVER
import (
"encoding/json"
"fmt"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
bankexported "github.com/cosmos/cosmos-sdk/x/bank/exported"
"github.com/cosmos/cosmos-sdk/x/genutil/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
@ -18,14 +16,14 @@ import (
// SetGenTxsInAppGenesisState - sets the genesis transactions in the app genesis state
func SetGenTxsInAppGenesisState(
cdc codec.JSONMarshaler, appGenesisState map[string]json.RawMessage, genTxs []authtypes.StdTx,
cdc codec.JSONMarshaler, txJSONEncoder sdk.TxEncoder, appGenesisState map[string]json.RawMessage, genTxs []sdk.Tx,
) (map[string]json.RawMessage, error) {
genesisState := types.GetGenesisStateFromAppState(cdc, appGenesisState)
genTxsBz := make([]json.RawMessage, 0, len(genTxs))
for _, genTx := range genTxs {
txBz, err := cdc.MarshalJSON(genTx)
txBz, err := txJSONEncoder(genTx)
if err != nil {
return appGenesisState, err
}
@ -90,19 +88,25 @@ func ValidateAccountInGenesis(
type deliverTxfn func(abci.RequestDeliverTx) abci.ResponseDeliverTx
// DeliverGenTxs iterates over all genesis txs, decodes each into a StdTx and
// invokes the provided deliverTxfn with the decoded StdTx. It returns the result
// DeliverGenTxs iterates over all genesis txs, decodes each into a Tx and
// invokes the provided deliverTxfn with the decoded Tx. It returns the result
// of the staking module's ApplyAndReturnValidatorSetUpdates.
func DeliverGenTxs(
ctx sdk.Context, cdc *codec.Codec, genTxs []json.RawMessage,
ctx sdk.Context, genTxs []json.RawMessage,
stakingKeeper types.StakingKeeper, deliverTx deliverTxfn,
txEncodingConfig client.TxEncodingConfig,
) []abci.ValidatorUpdate {
for _, genTx := range genTxs {
var tx authtypes.StdTx
cdc.MustUnmarshalJSON(genTx, &tx)
tx, err := txEncodingConfig.TxJSONDecoder()(genTx)
if err != nil {
panic(err)
}
bz := cdc.MustMarshalBinaryBare(tx)
bz, err := txEncodingConfig.TxEncoder()(tx)
if err != nil {
panic(err)
}
res := deliverTx(abci.RequestDeliverTx{Tx: bz})
if !res.IsOK() {

View File

@ -1,14 +1,280 @@
package genutil
package genutil_test
import "testing"
import (
"encoding/json"
"fmt"
"testing"
func TestGenTx(t *testing.T) {
"github.com/cosmos/cosmos-sdk/simapp"
"github.com/cosmos/cosmos-sdk/simapp/helpers"
simappparams "github.com/cosmos/cosmos-sdk/simapp/params"
sdk "github.com/cosmos/cosmos-sdk/types"
// TODO test that key overwrite flags work / no overwrites if set off
// TODO test validator created has provided pubkey
// TODO test the account created has the correct pubkey
"github.com/stretchr/testify/suite"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/crypto/secp256k1"
// TODO test must provide at least genesis transaction
// TODO test with both one and two genesis transactions:
// TODO correct: genesis account created, canididates created, pool token variance
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
"github.com/cosmos/cosmos-sdk/x/genutil"
"github.com/cosmos/cosmos-sdk/x/genutil/types"
staking "github.com/cosmos/cosmos-sdk/x/staking"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
)
var (
priv1 = secp256k1.GenPrivKey()
priv2 = secp256k1.GenPrivKey()
pk1 = priv1.PubKey()
pk2 = priv2.PubKey()
addr1 = sdk.AccAddress(pk1.Address())
addr2 = sdk.AccAddress(pk2.Address())
desc = stakingtypes.NewDescription("testname", "", "", "", "")
comm = stakingtypes.CommissionRates{}
msg1 = stakingtypes.NewMsgCreateValidator(sdk.ValAddress(pk1.Address()), pk1,
sdk.NewInt64Coin(sdk.DefaultBondDenom, 50), desc, comm, sdk.OneInt())
msg2 = stakingtypes.NewMsgCreateValidator(sdk.ValAddress(pk2.Address()), pk1,
sdk.NewInt64Coin(sdk.DefaultBondDenom, 50), desc, comm, sdk.OneInt())
)
// GenTxTestSuite is a test suite to be used with gentx tests.
type GenTxTestSuite struct {
suite.Suite
ctx sdk.Context
app *simapp.SimApp
encodingConfig simappparams.EncodingConfig
}
func (suite *GenTxTestSuite) SetupTest() {
checkTx := false
app := simapp.Setup(checkTx)
suite.ctx = app.BaseApp.NewContext(checkTx, abci.Header{})
suite.app = app
suite.encodingConfig = simapp.MakeEncodingConfig()
}
func (suite *GenTxTestSuite) setAccountBalance(addr sdk.AccAddress, amount int64) json.RawMessage {
acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr)
suite.app.AccountKeeper.SetAccount(suite.ctx, acc)
err := suite.app.BankKeeper.SetBalances(
suite.ctx, addr, sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 25)},
)
suite.Require().NoError(err)
bankGenesisState := suite.app.BankKeeper.ExportGenesis(suite.ctx)
bankGenesis, err := suite.encodingConfig.Amino.MarshalJSON(bankGenesisState) // TODO switch this to use Marshaler
suite.Require().NoError(err)
return bankGenesis
}
func (suite *GenTxTestSuite) TestSetGenTxsInAppGenesisState() {
var (
txBuilder = suite.encodingConfig.TxConfig.NewTxBuilder()
genTxs []sdk.Tx
)
testCases := []struct {
msg string
malleate func()
expPass bool
}{
{
"one genesis transaction",
func() {
err := txBuilder.SetMsgs(msg1)
suite.Require().NoError(err)
tx := txBuilder.GetTx()
genTxs = []sdk.Tx{tx}
},
true,
},
{
"two genesis transactions",
func() {
err := txBuilder.SetMsgs(msg1, msg2)
suite.Require().NoError(err)
tx := txBuilder.GetTx()
genTxs = []sdk.Tx{tx}
},
true,
},
}
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
suite.SetupTest()
cdc := suite.encodingConfig.Marshaler
txJSONEncoder := suite.encodingConfig.TxConfig.TxJSONEncoder()
tc.malleate()
appGenesisState, err := genutil.SetGenTxsInAppGenesisState(cdc, txJSONEncoder, make(map[string]json.RawMessage), genTxs)
if tc.expPass {
suite.Require().NoError(err)
suite.Require().NotNil(appGenesisState[types.ModuleName])
var genesisState types.GenesisState
err := cdc.UnmarshalJSON(appGenesisState[types.ModuleName], &genesisState)
suite.Require().NoError(err)
suite.Require().NotNil(genesisState.GenTxs)
} else {
suite.Require().Error(err)
}
})
}
}
func (suite *GenTxTestSuite) TestValidateAccountInGenesis() {
var (
appGenesisState = make(map[string]json.RawMessage)
coins sdk.Coins
)
testCases := []struct {
msg string
malleate func()
expPass bool
}{
{
"no accounts",
func() {
coins = sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 0)}
},
false,
},
{
"account without balance in the genesis state",
func() {
coins = sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 0)}
appGenesisState[banktypes.ModuleName] = suite.setAccountBalance(addr2, 50)
},
false,
},
{
"account without enough funds of default bond denom",
func() {
coins = sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 50)}
appGenesisState[banktypes.ModuleName] = suite.setAccountBalance(addr1, 25)
},
false,
},
{
"account with enough funds of default bond denom",
func() {
coins = sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 10)}
appGenesisState[banktypes.ModuleName] = suite.setAccountBalance(addr1, 25)
},
true,
},
}
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
suite.SetupTest()
cdc := suite.encodingConfig.Marshaler
suite.app.StakingKeeper.SetParams(suite.ctx, stakingtypes.DefaultParams())
stakingGenesisState := staking.ExportGenesis(suite.ctx, suite.app.StakingKeeper)
suite.Require().Equal(stakingGenesisState.Params, stakingtypes.DefaultParams())
stakingGenesis, err := cdc.MarshalJSON(stakingGenesisState) // TODO switch this to use Marshaler
suite.Require().NoError(err)
appGenesisState[stakingtypes.ModuleName] = stakingGenesis
tc.malleate()
err = genutil.ValidateAccountInGenesis(
appGenesisState, banktypes.GenesisBalancesIterator{},
addr1, coins, cdc,
)
if tc.expPass {
suite.Require().NoError(err)
} else {
suite.Require().Error(err)
}
})
}
}
func (suite *GenTxTestSuite) TestDeliverGenTxs() {
var (
genTxs []json.RawMessage
txBuilder = suite.encodingConfig.TxConfig.NewTxBuilder()
)
testCases := []struct {
msg string
malleate func()
expPass bool
}{
{
"no signature supplied",
func() {
err := txBuilder.SetMsgs(msg1)
suite.Require().NoError(err)
genTxs = make([]json.RawMessage, 1)
tx, err := suite.encodingConfig.TxConfig.TxJSONEncoder()(txBuilder.GetTx())
suite.Require().NoError(err)
genTxs[0] = tx
},
false,
},
{
"success",
func() {
_ = suite.setAccountBalance(addr1, 50)
_ = suite.setAccountBalance(addr2, 0)
msg := banktypes.NewMsgSend(addr1, addr2, sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 1)})
tx, err := helpers.GenTx(
suite.encodingConfig.TxConfig,
[]sdk.Msg{msg},
sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 10)},
helpers.DefaultGenTxGas,
suite.ctx.ChainID(),
[]uint64{0},
[]uint64{0},
priv1,
)
suite.Require().NoError(err)
genTxs = make([]json.RawMessage, 1)
genTx, err := suite.encodingConfig.TxConfig.TxJSONEncoder()(tx)
suite.Require().NoError(err)
genTxs[0] = genTx
},
true,
},
}
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
suite.SetupTest()
tc.malleate()
if tc.expPass {
suite.Require().NotPanics(func() {
genutil.DeliverGenTxs(
suite.ctx, genTxs, suite.app.StakingKeeper, suite.app.BaseApp.DeliverTx,
suite.encodingConfig.TxConfig,
)
})
} else {
suite.Require().Panics(func() {
genutil.DeliverGenTxs(
suite.ctx, genTxs, suite.app.StakingKeeper, suite.app.BaseApp.DeliverTx,
suite.encodingConfig.TxConfig,
)
})
}
})
}
}
func TestGenTxTestSuite(t *testing.T) {
suite.Run(t, new(GenTxTestSuite))
}

View File

@ -43,13 +43,13 @@ func (AppModuleBasic) DefaultGenesis(cdc codec.JSONMarshaler) json.RawMessage {
}
// ValidateGenesis performs genesis state validation for the genutil module.
func (AppModuleBasic) ValidateGenesis(cdc codec.JSONMarshaler, bz json.RawMessage) error {
func (b AppModuleBasic) ValidateGenesis(cdc codec.JSONMarshaler, txEncodingConfig client.TxEncodingConfig, bz json.RawMessage) error {
var data types.GenesisState
if err := cdc.UnmarshalJSON(bz, &data); err != nil {
return fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err)
}
return types.ValidateGenesis(data)
return types.ValidateGenesis(data, txEncodingConfig.TxJSONDecoder())
}
// RegisterRESTRoutes registers the REST routes for the genutil module.
@ -67,20 +67,24 @@ func (AppModuleBasic) GetQueryCmd() *cobra.Command { return nil }
type AppModule struct {
AppModuleBasic
accountKeeper types.AccountKeeper
stakingKeeper types.StakingKeeper
deliverTx deliverTxfn
accountKeeper types.AccountKeeper
stakingKeeper types.StakingKeeper
deliverTx deliverTxfn
txEncodingConfig client.TxEncodingConfig
}
// NewAppModule creates a new AppModule object
func NewAppModule(accountKeeper types.AccountKeeper,
stakingKeeper types.StakingKeeper, deliverTx deliverTxfn) module.AppModule {
stakingKeeper types.StakingKeeper, deliverTx deliverTxfn,
txEncodingConfig client.TxEncodingConfig,
) module.AppModule {
return module.NewGenesisOnlyAppModule(AppModule{
AppModuleBasic: AppModuleBasic{},
accountKeeper: accountKeeper,
stakingKeeper: stakingKeeper,
deliverTx: deliverTx,
AppModuleBasic: AppModuleBasic{},
accountKeeper: accountKeeper,
stakingKeeper: stakingKeeper,
deliverTx: deliverTx,
txEncodingConfig: txEncodingConfig,
})
}
@ -89,7 +93,7 @@ func NewAppModule(accountKeeper types.AccountKeeper,
func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONMarshaler, data json.RawMessage) []abci.ValidatorUpdate {
var genesisState types.GenesisState
cdc.MustUnmarshalJSON(data, &genesisState)
return InitGenesis(ctx, types.ModuleCdc, am.stakingKeeper, am.deliverTx, genesisState)
return InitGenesis(ctx, am.stakingKeeper, am.deliverTx, genesisState, am.txEncodingConfig)
}
// ExportGenesis returns the exported genesis state as raw bytes for the genutil

View File

@ -9,7 +9,7 @@ import (
tmtypes "github.com/tendermint/tendermint/types"
"github.com/cosmos/cosmos-sdk/codec"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
sdk "github.com/cosmos/cosmos-sdk/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
)
@ -36,9 +36,9 @@ func DefaultGenesisState() GenesisState {
}
}
// NewGenesisStateFromStdTx creates a new GenesisState object
// NewGenesisStateFromTx creates a new GenesisState object
// from auth transactions
func NewGenesisStateFromStdTx(genTxs []authtypes.StdTx) GenesisState {
func NewGenesisStateFromTx(genTxs []sdk.Tx) GenesisState {
genTxsBz := make([]json.RawMessage, len(genTxs))
for i, genTx := range genTxs {
genTxsBz[i] = ModuleCdc.MustMarshalJSON(genTx)
@ -98,17 +98,18 @@ func GenesisStateFromGenFile(cdc codec.JSONMarshaler, genFile string) (genesisSt
}
// ValidateGenesis validates GenTx transactions
func ValidateGenesis(genesisState GenesisState) error {
func ValidateGenesis(genesisState GenesisState, txJSONDecoder sdk.TxDecoder) error {
for i, genTx := range genesisState.GenTxs {
var tx authtypes.StdTx
if err := ModuleCdc.UnmarshalJSON(genTx, &tx); err != nil {
var tx sdk.Tx
tx, err := txJSONDecoder(genTx)
if err != nil {
return err
}
msgs := tx.GetMsgs()
if len(msgs) != 1 {
return errors.New(
"must provide genesis StdTx with exactly 1 CreateValidator message")
"must provide genesis Tx with exactly 1 CreateValidator message")
}
// TODO: abstract back to staking

View File

@ -1,4 +1,4 @@
package types
package types_test
import (
"encoding/json"
@ -8,8 +8,10 @@ import (
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/crypto/ed25519"
"github.com/cosmos/cosmos-sdk/simapp"
"github.com/cosmos/cosmos-sdk/simapp/params"
sdk "github.com/cosmos/cosmos-sdk/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/cosmos/cosmos-sdk/x/genutil/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
)
@ -19,10 +21,10 @@ var (
)
func TestNetGenesisState(t *testing.T) {
gen := NewGenesisState(nil)
gen := types.NewGenesisState(nil)
assert.NotNil(t, gen.GenTxs) // https://github.com/cosmos/cosmos-sdk/issues/5086
gen = NewGenesisState(
gen = types.NewGenesisState(
[]json.RawMessage{
[]byte(`{"foo":"bar"}`),
},
@ -31,7 +33,6 @@ func TestNetGenesisState(t *testing.T) {
}
func TestValidateGenesisMultipleMessages(t *testing.T) {
desc := stakingtypes.NewDescription("testname", "", "", "", "")
comm := stakingtypes.CommissionRates{}
@ -41,10 +42,15 @@ func TestValidateGenesisMultipleMessages(t *testing.T) {
msg2 := stakingtypes.NewMsgCreateValidator(sdk.ValAddress(pk2.Address()), pk2,
sdk.NewInt64Coin(sdk.DefaultBondDenom, 50), desc, comm, sdk.OneInt())
genTxs := authtypes.NewStdTx([]sdk.Msg{msg1, msg2}, authtypes.StdFee{}, nil, "")
genesisState := NewGenesisStateFromStdTx([]authtypes.StdTx{genTxs})
txGen := params.MakeEncodingConfig().TxConfig
txBuilder := txGen.NewTxBuilder()
err := txBuilder.SetMsgs(msg1, msg2)
require.NoError(t, err)
err := ValidateGenesis(genesisState)
tx := txBuilder.GetTx()
genesisState := types.NewGenesisStateFromTx([]sdk.Tx{tx})
err = types.ValidateGenesis(genesisState, simapp.MakeEncodingConfig().TxConfig.TxJSONDecoder())
require.Error(t, err)
}
@ -53,9 +59,14 @@ func TestValidateGenesisBadMessage(t *testing.T) {
msg1 := stakingtypes.NewMsgEditValidator(sdk.ValAddress(pk1.Address()), desc, nil, nil)
genTxs := authtypes.NewStdTx([]sdk.Msg{msg1}, authtypes.StdFee{}, nil, "")
genesisState := NewGenesisStateFromStdTx([]authtypes.StdTx{genTxs})
txGen := params.MakeEncodingConfig().TxConfig
txBuilder := txGen.NewTxBuilder()
err := txBuilder.SetMsgs(msg1)
require.NoError(t, err)
err := ValidateGenesis(genesisState)
tx := txBuilder.GetTx()
genesisState := types.NewGenesisStateFromTx([]sdk.Tx{tx})
err = types.ValidateGenesis(genesisState, simapp.MakeEncodingConfig().TxConfig.TxJSONDecoder())
require.Error(t, err)
}

View File

@ -64,7 +64,7 @@ func (AppModuleBasic) DefaultGenesis(cdc codec.JSONMarshaler) json.RawMessage {
}
// ValidateGenesis performs genesis state validation for the gov module.
func (AppModuleBasic) ValidateGenesis(cdc codec.JSONMarshaler, bz json.RawMessage) error {
func (AppModuleBasic) ValidateGenesis(cdc codec.JSONMarshaler, config client.TxEncodingConfig, bz json.RawMessage) error {
var data types.GenesisState
if err := cdc.UnmarshalJSON(bz, &data); err != nil {
return fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err)

View File

@ -56,7 +56,7 @@ func (AppModuleBasic) DefaultGenesis(cdc codec.JSONMarshaler) json.RawMessage {
}
// ValidateGenesis performs genesis state validation for the ibc transfer module.
func (AppModuleBasic) ValidateGenesis(cdc codec.JSONMarshaler, bz json.RawMessage) error {
func (AppModuleBasic) ValidateGenesis(cdc codec.JSONMarshaler, config client.TxEncodingConfig, bz json.RawMessage) error {
var gs types.GenesisState
if err := cdc.UnmarshalJSON(bz, &gs); err != nil {
return fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err)

View File

@ -54,7 +54,7 @@ func (AppModuleBasic) DefaultGenesis(cdc codec.JSONMarshaler) json.RawMessage {
}
// ValidateGenesis performs genesis state validation for the ibc module.
func (AppModuleBasic) ValidateGenesis(cdc codec.JSONMarshaler, bz json.RawMessage) error {
func (AppModuleBasic) ValidateGenesis(cdc codec.JSONMarshaler, config client.TxEncodingConfig, bz json.RawMessage) error {
var gs types.GenesisState
if err := cdc.UnmarshalJSON(bz, &gs); err != nil {
return fmt.Errorf("failed to unmarshal %s genesis state: %w", host.ModuleName, err)

View File

@ -54,7 +54,7 @@ func (AppModuleBasic) DefaultGenesis(cdc codec.JSONMarshaler) json.RawMessage {
}
// ValidateGenesis performs genesis state validation for the mint module.
func (AppModuleBasic) ValidateGenesis(cdc codec.JSONMarshaler, bz json.RawMessage) error {
func (AppModuleBasic) ValidateGenesis(cdc codec.JSONMarshaler, config client.TxEncodingConfig, bz json.RawMessage) error {
var data types.GenesisState
if err := cdc.UnmarshalJSON(bz, &data); err != nil {
return fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err)

View File

@ -47,7 +47,9 @@ func (AppModuleBasic) RegisterCodec(cdc *codec.Codec) {
func (AppModuleBasic) DefaultGenesis(_ codec.JSONMarshaler) json.RawMessage { return nil }
// ValidateGenesis performs genesis state validation for the params module.
func (AppModuleBasic) ValidateGenesis(_ codec.JSONMarshaler, _ json.RawMessage) error { return nil }
func (AppModuleBasic) ValidateGenesis(_ codec.JSONMarshaler, config client.TxEncodingConfig, _ json.RawMessage) error {
return nil
}
// RegisterRESTRoutes registers the REST routes for the params module.
func (AppModuleBasic) RegisterRESTRoutes(_ client.Context, _ *mux.Router) {}

View File

@ -61,7 +61,7 @@ func (AppModuleBasic) DefaultGenesis(cdc codec.JSONMarshaler) json.RawMessage {
}
// ValidateGenesis performs genesis state validation for the slashing module.
func (AppModuleBasic) ValidateGenesis(cdc codec.JSONMarshaler, bz json.RawMessage) error {
func (AppModuleBasic) ValidateGenesis(cdc codec.JSONMarshaler, config client.TxEncodingConfig, bz json.RawMessage) error {
var data types.GenesisState
if err := cdc.UnmarshalJSON(bz, &data); err != nil {
return fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err)

View File

@ -59,7 +59,7 @@ func (AppModuleBasic) DefaultGenesis(cdc codec.JSONMarshaler) json.RawMessage {
}
// ValidateGenesis performs genesis state validation for the staking module.
func (AppModuleBasic) ValidateGenesis(cdc codec.JSONMarshaler, bz json.RawMessage) error {
func (AppModuleBasic) ValidateGenesis(cdc codec.JSONMarshaler, config client.TxEncodingConfig, bz json.RawMessage) error {
var data types.GenesisState
if err := cdc.UnmarshalJSON(bz, &data); err != nil {
return fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err)

View File

@ -110,7 +110,7 @@ func (AppModuleBasic) DefaultGenesis(_ codec.JSONMarshaler) json.RawMessage {
}
// ValidateGenesis is always successful, as we ignore the value
func (AppModuleBasic) ValidateGenesis(_ codec.JSONMarshaler, _ json.RawMessage) error {
func (AppModuleBasic) ValidateGenesis(_ codec.JSONMarshaler, config client.TxEncodingConfig, _ json.RawMessage) error {
return nil
}