Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support extension options for build tx #15992

Merged
merged 6 commits into from
Apr 30, 2023
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
* (telemetry) [#15657](https://github.com/cosmos/cosmos-sdk/pull/15657) Emit more data (go version, sdk version, upgrade height) in prom metrics
* (modulemanager) [#15829](https://github.com/cosmos/cosmos-sdk/pull/15829) add new endblocker interface to handle valset updates
* (core) [#14860](https://github.com/cosmos/cosmos-sdk/pull/14860) Add `Precommit` and `PrepareCheckState` AppModule callbacks.
* (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 @@ -281,6 +283,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 @@ -329,6 +353,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
65 changes: 31 additions & 34 deletions client/tx/tx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,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()
defaultSignMode, err := signing.APISignModeToInternal(txCfg.SignModeHandler().DefaultMode())
Expand All @@ -117,16 +127,7 @@ func TestBuildSimTx(t *testing.T) {
_, _, 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(defaultSignMode).
WithKeybase(kb)

txf := mockTxFactory(txCfg).WithSignMode(defaultSignMode).WithKeybase(kb)
msg := banktypes.NewMsgSend(sdk.AccAddress("from"), sdk.AccAddress("to"), nil)
bz, err := txf.BuildSimTx(msg)
require.NoError(t, err)
Expand All @@ -142,16 +143,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 @@ -162,6 +154,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()
kb, err := keyring.New(t.Name(), "test", t.TempDir(), nil, cdc)
Expand Down Expand Up @@ -238,13 +247,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 @@ -405,13 +408,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
5 changes: 5 additions & 0 deletions client/tx_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package client

import (
txsigning "cosmossdk.io/x/tx/signing"
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 @@ -49,4 +50,8 @@ type (
SetFeeGranter(feeGranter sdk.AccAddress)
AddAuxSignerData(tx.AuxSignerData) error
}

mmsqe marked this conversation as resolved.
Show resolved Hide resolved
ExtendedTxBuilder interface {
julienrbrt marked this conversation as resolved.
Show resolved Hide resolved
SetExtensionOptions(extOpts ...*codectypes.Any)
}
)
29 changes: 29 additions & 0 deletions types/module/testutil/codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,32 @@ func MakeTestTxConfig() client.TxConfig {
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
}