feat: support extension options for build tx (#15992)
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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"
|
||||
@@ -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
|
||||
@@ -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) {
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
+31
-34
@@ -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())
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
|
||||
@@ -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"
|
||||
@@ -49,4 +50,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)
|
||||
}
|
||||
)
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user