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(cosmosclient): add tx options (incl memo setting) (backport #4276) #4279

Merged
merged 4 commits into from
Jul 29, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
4 changes: 4 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@

## [`v28.5.1`](https://github.com/ignite/cli/releases/tag/v28.5.1)

### Features
julienrbrt marked this conversation as resolved.
Show resolved Hide resolved

- [#4276](https://github.com/ignite/cli/pull/4276) Add `cosmosclient.CreateTxWithOptions` method to facilite more custom tx creation

### Changes

- [#4262](https://github.com/ignite/cli/pull/4262) Bring back relayer command
Expand Down
70 changes: 47 additions & 23 deletions ignite/pkg/cosmosclient/cosmosclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@ type Client struct {
}

// Option configures your client.
// Option, are global to the client and affect all transactions.
// If you want to override a global option on a transaction, use the TxOptions struct.
type Option func(*Client)

// WithHome sets the data dir of your chain. This option is used to access your chain's
Expand Down Expand Up @@ -175,12 +177,14 @@ func WithNodeAddress(addr string) Option {
}
}

// WithAddressPrefix sets the address prefix on the client.
func WithAddressPrefix(prefix string) Option {
return func(c *Client) {
c.addressPrefix = prefix
}
}

// WithUseFaucet sets the faucet address on the client.
func WithUseFaucet(faucetAddress, denom string, minAmount uint64) Option {
return func(c *Client) {
c.useFaucet = true
Expand Down Expand Up @@ -216,7 +220,8 @@ func WithGasAdjustment(gasAdjustment float64) Option {
}
}

// WithFees sets the fees (e.g. 10uatom).
// WithFees sets the fees (e.g. 10uatom) on the client.
// It will be used for all transactions if not overridden on the transaction options.
func WithFees(fees string) Option {
return func(c *Client) {
c.fees = fees
Expand Down Expand Up @@ -544,15 +549,17 @@ func (c Client) BroadcastTx(ctx context.Context, account cosmosaccount.Account,
return txService.Broadcast(ctx)
}

func (c Client) CreateTx(goCtx context.Context, account cosmosaccount.Account, msgs ...sdktypes.Msg) (TxService, error) {
// CreateTxWithOptions creates a transaction with the given options.
// Options override global client options.
func (c Client) CreateTxWithOptions(ctx context.Context, account cosmosaccount.Account, options TxOptions, msgs ...sdktypes.Msg) (TxService, error) {
defer c.lockBech32Prefix()()

if c.useFaucet && !c.generateOnly {
addr, err := account.Address(c.addressPrefix)
if err != nil {
return TxService{}, errors.WithStack(err)
}
if err := c.makeSureAccountHasTokens(goCtx, addr); err != nil {
if err := c.makeSureAccountHasTokens(ctx, addr); err != nil {
return TxService{}, err
}
}
Expand All @@ -562,36 +569,49 @@ func (c Client) CreateTx(goCtx context.Context, account cosmosaccount.Account, m
return TxService{}, errors.WithStack(err)
}

ctx := c.context.
clientCtx := c.context.
WithFromName(account.Name).
WithFromAddress(sdkaddr)

txf, err := c.prepareFactory(ctx)
txf, err := c.prepareFactory(clientCtx)
if err != nil {
return TxService{}, err
}

if c.gasAdjustment != 0 && c.gasAdjustment != defaultGasAdjustment {
txf = txf.WithGasAdjustment(c.gasAdjustment)
if options.Memo != "" {
txf = txf.WithMemo(options.Memo)
}

var gas uint64
if c.gas != "" && c.gas != GasAuto {
gas, err = strconv.ParseUint(c.gas, 10, 64)
if err != nil {
return TxService{}, errors.WithStack(err)
}
txf = txf.WithFees(c.fees)
if options.Fees != "" {
txf = txf.WithFees(options.Fees)
}

if options.GasLimit != 0 {
txf = txf.WithGas(options.GasLimit)
} else {
_, gas, err = c.gasometer.CalculateGas(ctx, txf, msgs...)
if err != nil {
return TxService{}, errors.WithStack(err)
if c.gasAdjustment != 0 && c.gasAdjustment != defaultGasAdjustment {
txf = txf.WithGasAdjustment(c.gasAdjustment)
}
// the simulated gas can vary from the actual gas needed for a real transaction
// we add an amount to ensure sufficient gas is provided
gas += 20000

var gas uint64
if c.gas != "" && c.gas != GasAuto {
gas, err = strconv.ParseUint(c.gas, 10, 64)
if err != nil {
return TxService{}, errors.WithStack(err)
}
} else {
_, gas, err = c.gasometer.CalculateGas(clientCtx, txf, msgs...)
if err != nil {
return TxService{}, errors.WithStack(err)
}
// the simulated gas can vary from the actual gas needed for a real transaction
// we add an amount to ensure sufficient gas is provided
gas += 20000
}

txf = txf.WithGas(gas)
}
txf = txf.WithGas(gas)
txf = txf.WithFees(c.fees)

if c.gasPrices != "" {
txf = txf.WithGasPrices(c.gasPrices)
Expand All @@ -602,16 +622,20 @@ func (c Client) CreateTx(goCtx context.Context, account cosmosaccount.Account, m
return TxService{}, errors.WithStack(err)
}

txUnsigned.SetFeeGranter(ctx.GetFeeGranterAddress())
txUnsigned.SetFeeGranter(clientCtx.GetFeeGranterAddress())

return TxService{
client: c,
clientContext: ctx,
clientContext: clientCtx,
txBuilder: txUnsigned,
txFactory: txf,
}, nil
}

func (c Client) CreateTx(ctx context.Context, account cosmosaccount.Account, msgs ...sdktypes.Msg) (TxService, error) {
return c.CreateTxWithOptions(ctx, account, TxOptions{}, msgs...)
}

// GetBlockTXs returns the transactions in a block.
// The list of transactions can be empty if there are no transactions in the block
// at the moment this method is called.
Expand Down
1 change: 0 additions & 1 deletion ignite/pkg/cosmosclient/rpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import (
// Useful because the original implementation may return JSON errors when the
// requested node is busy, which is confusing for the user. With rpcWrapper,
// the error is prefixed with 'error while requesting node xxx: JSON error'.
// TODO(tb): we may remove this wrapper once https://github.com/tendermint/tendermint/issues/9312 is fixed.
type rpcWrapper struct {
rpcclient.Client
nodeAddress string
Expand Down
2 changes: 2 additions & 0 deletions ignite/pkg/cosmosclient/signer.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import (
"github.com/cosmos/cosmos-sdk/client/tx"
)

var _ Signer = signer{}

// signer implements the Signer interface.
type signer struct{}

Expand Down
15 changes: 15 additions & 0 deletions ignite/pkg/cosmosclient/tx_options.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package cosmosclient

// TxOptions contains options for creating a transaction.
// It is used by the CreateTxWithOptions method.
type TxOptions struct {
// Memo is the memo to be used for the transaction.
Memo string

// GasLimit is the gas limit to be used for the transaction.
// If GasLimit is set to 0, the gas limit will be automatically calculated.
GasLimit uint64

// Fees is the fees to be used for the transaction.
Fees string
}
Loading