Skip to content

Commit

Permalink
feat: support extension options for build tx (backport: #15992) (#16317)
Browse files Browse the repository at this point in the history
  • Loading branch information
mmsqe committed May 28, 2023
1 parent 40622ff commit 6d95900
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 35 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ Ref: https://keepachangelog.com/en/1.0.0/

* (baseapp) [#16290](https://github.com/cosmos/cosmos-sdk/pull/16290) Add circuit breaker setter in baseapp.
* (x/group) [#16191](https://github.com/cosmos/cosmos-sdk/pull/16191) Add EventProposalPruned event to group module whenever a proposal is pruned.
* (tx) [#15992](https://github.com/cosmos/cosmos-sdk/pull/15992) Add `WithExtensionOptions` in tx Factory to allow `SetExtensionOptions` with given extension options.

### Improvements

Expand Down
28 changes: 28 additions & 0 deletions client/tx/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (

"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
Expand Down Expand Up @@ -41,6 +42,7 @@ type Factory struct {
feeGranter sdk.AccAddress
feePayer sdk.AccAddress
gasPrices sdk.DecCoins
extOptions []*codectypes.Any
signMode signing.SignMode
simulateAndExecute bool
preprocessTxHook client.PreprocessTxFn
Expand Down Expand Up @@ -279,6 +281,28 @@ func (f Factory) PreprocessTx(keyname string, builder client.TxBuilder) error {
return f.preprocessTxHook(f.chainID, key.GetType(), builder)
}

// WithExtensionOptions returns a Factory with given extension options added to the existing options,
// Example to add dynamic fee extension options:
//
// extOpt := ethermint.ExtensionOptionDynamicFeeTx{
// MaxPriorityPrice: sdk.NewInt(1000000),
// }
//
// extBytes, _ := extOpt.Marshal()
//
// extOpts := []*types.Any{
// {
// TypeUrl: "/ethermint.types.v1.ExtensionOptionDynamicFeeTx",
// Value: extBytes,
// },
// }
//
// txf.WithExtensionOptions(extOpts...)
func (f Factory) WithExtensionOptions(extOpts ...*codectypes.Any) Factory {
f.extOptions = extOpts
return f
}

// BuildUnsignedTx builds a transaction to be signed given a set of messages.
// Once created, the fee, memo, and messages are set.
func (f Factory) BuildUnsignedTx(msgs ...sdk.Msg) (client.TxBuilder, error) {
Expand Down Expand Up @@ -327,6 +351,10 @@ func (f Factory) BuildUnsignedTx(msgs ...sdk.Msg) (client.TxBuilder, error) {
tx.SetFeePayer(f.feePayer)
tx.SetTimeoutHeight(f.TimeoutHeight())

if etx, ok := tx.(client.ExtendedTxBuilder); ok {
etx.SetExtensionOptions(f.extOptions...)
}

return tx, nil
}

Expand Down
67 changes: 32 additions & 35 deletions client/tx/tx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
"github.com/cosmos/cosmos-sdk/testutil/testdata"
sdk "github.com/cosmos/cosmos-sdk/types"
moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil"
txtypes "github.com/cosmos/cosmos-sdk/types/tx"
signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing"
ante "github.com/cosmos/cosmos-sdk/x/auth/ante"
Expand Down Expand Up @@ -108,6 +109,16 @@ func TestCalculateGas(t *testing.T) {
}
}

func mockTxFactory(txCfg client.TxConfig) tx.Factory {
return tx.Factory{}.
WithTxConfig(txCfg).
WithAccountNumber(50).
WithSequence(23).
WithFees("50stake").
WithMemo("memo").
WithChainID("test-chain")
}

func TestBuildSimTx(t *testing.T) {
txCfg, cdc := newTestTxConfig(t)

Expand All @@ -117,17 +128,7 @@ func TestBuildSimTx(t *testing.T) {
path := hd.CreateHDPath(118, 0, 0).String()
_, _, err = kb.NewMnemonic("test_key1", keyring.English, path, keyring.DefaultBIP39Passphrase, hd.Secp256k1)
require.NoError(t, err)

txf := tx.Factory{}.
WithTxConfig(txCfg).
WithAccountNumber(50).
WithSequence(23).
WithFees("50stake").
WithMemo("memo").
WithChainID("test-chain").
WithSignMode(txCfg.SignModeHandler().DefaultMode()).
WithKeybase(kb)

txf := mockTxFactory(txCfg).WithSignMode(txCfg.SignModeHandler().DefaultMode()).WithKeybase(kb)
msg := banktypes.NewMsgSend(sdk.AccAddress("from"), sdk.AccAddress("to"), nil)
bz, err := txf.BuildSimTx(msg)
require.NoError(t, err)
Expand All @@ -143,16 +144,7 @@ func TestBuildUnsignedTx(t *testing.T) {

_, _, err = kb.NewMnemonic("test_key1", keyring.English, path, keyring.DefaultBIP39Passphrase, hd.Secp256k1)
require.NoError(t, err)

txf := tx.Factory{}.
WithTxConfig(txConfig).
WithAccountNumber(50).
WithSequence(23).
WithFees("50stake").
WithMemo("memo").
WithChainID("test-chain").
WithKeybase(kb)

txf := mockTxFactory(txConfig).WithKeybase(kb)
msg := banktypes.NewMsgSend(sdk.AccAddress("from"), sdk.AccAddress("to"), nil)
tx, err := txf.BuildUnsignedTx(msg)
require.NoError(t, err)
Expand All @@ -163,6 +155,23 @@ func TestBuildUnsignedTx(t *testing.T) {
require.Empty(t, sigs)
}

func TestBuildUnsignedTxWithWithExtensionOptions(t *testing.T) {
txCfg := moduletestutil.MakeBuilderTestTxConfig()
extOpts := []*codectypes.Any{
{
TypeUrl: "/test",
Value: []byte("test"),
},
}
txf := mockTxFactory(txCfg).WithExtensionOptions(extOpts...)
msg := banktypes.NewMsgSend(sdk.AccAddress("from"), sdk.AccAddress("to"), nil)
tx, err := txf.BuildUnsignedTx(msg)
require.NoError(t, err)
require.NotNil(t, tx)
txb := tx.(*moduletestutil.TestTxBuilder)
require.Equal(t, extOpts, txb.ExtOptions)
}

func TestMnemonicInMemo(t *testing.T) {
txConfig, cdc := newTestTxConfig(t)
kb, err := keyring.New(t.Name(), "test", t.TempDir(), nil, cdc)
Expand Down Expand Up @@ -239,13 +248,7 @@ func TestSign(t *testing.T) {
requireT.NotEqual(pubKey1.Bytes(), pubKey2.Bytes())
t.Log("Pub keys:", pubKey1, pubKey2)

txfNoKeybase := tx.Factory{}.
WithTxConfig(txConfig).
WithAccountNumber(50).
WithSequence(23).
WithFees("50stake").
WithMemo("memo").
WithChainID("test-chain")
txfNoKeybase := mockTxFactory(txConfig)
txfDirect := txfNoKeybase.
WithKeybase(kb).
WithSignMode(signingtypes.SignMode_SIGN_MODE_DIRECT)
Expand Down Expand Up @@ -406,13 +409,7 @@ func TestPreprocessHook(t *testing.T) {
return nil
})

txfDirect := tx.Factory{}.
WithTxConfig(txConfig).
WithAccountNumber(50).
WithSequence(23).
WithFees("50stake").
WithMemo("memo").
WithChainID("test-chain").
txfDirect := mockTxFactory(txConfig).
WithKeybase(kb).
WithSignMode(signingtypes.SignMode_SIGN_MODE_DIRECT).
WithPreprocessTxHook(preprocessHook)
Expand Down
7 changes: 7 additions & 0 deletions client/tx_config.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package client

import (
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/tx"
signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing"
Expand Down Expand Up @@ -48,4 +49,10 @@ type (
SetFeeGranter(feeGranter sdk.AccAddress)
AddAuxSignerData(tx.AuxSignerData) error
}

// ExtendedTxBuilder extends the TxBuilder interface,
// which is used to set extension options to be included in a transaction.
ExtendedTxBuilder interface {
SetExtensionOptions(extOpts ...*codectypes.Any)
}
)
35 changes: 35 additions & 0 deletions types/module/testutil/codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,38 @@ func MakeTestEncodingConfig(modules ...module.AppModuleBasic) TestEncodingConfig

return encCfg
}

func MakeTestTxConfig() client.TxConfig {
interfaceRegistry := types.NewInterfaceRegistry()
cdc := codec.NewProtoCodec(interfaceRegistry)
return tx.NewTxConfig(cdc, tx.DefaultSignModes)
}

type TestBuilderTxConfig struct {
client.TxConfig
TxBuilder *TestTxBuilder
}

func MakeBuilderTestTxConfig() TestBuilderTxConfig {
return TestBuilderTxConfig{
TxConfig: MakeTestTxConfig(),
}
}

func (cfg TestBuilderTxConfig) NewTxBuilder() client.TxBuilder {
if cfg.TxBuilder == nil {
cfg.TxBuilder = &TestTxBuilder{
TxBuilder: cfg.TxConfig.NewTxBuilder(),
}
}
return cfg.TxBuilder
}

type TestTxBuilder struct {
client.TxBuilder
ExtOptions []*types.Any
}

func (b *TestTxBuilder) SetExtensionOptions(extOpts ...*types.Any) {
b.ExtOptions = extOpts
}

0 comments on commit 6d95900

Please sign in to comment.