Skip to content

Commit

Permalink
feat(tx)!: make timeout_height time based (#20870)
Browse files Browse the repository at this point in the history
Co-authored-by: Marko <[email protected]>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
  • Loading branch information
3 people authored Jul 29, 2024
1 parent 9b6f61e commit 5853356
Show file tree
Hide file tree
Showing 31 changed files with 736 additions and 477 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ Every module contains its own CHANGELOG.md. Please refer to the module you are i
* (client) [#19870](https://github.com/cosmos/cosmos-sdk/pull/19870) Add new query command `wait-tx`. Alias `event-query-tx-for` to `wait-tx` for backward compatibility.
* (crypto/keyring) [#20212](https://github.com/cosmos/cosmos-sdk/pull/20212) Expose the db keyring used in the keystore.
* (genutil) [#19971](https://github.com/cosmos/cosmos-sdk/pull/19971) Allow manually setting the consensus key type in genesis
* (client/tx) [#20870](https://github.com/cosmos/cosmos-sdk/pull/20870) Add `timeout-timestamp` field for tx body defines time based timeout.Add `WithTimeoutTimestamp` to tx factory. Increased gas cost for processing newly added timeout timestamp field in tx body.

### Improvements

Expand Down Expand Up @@ -200,12 +201,13 @@ Every module contains its own CHANGELOG.md. Please refer to the module you are i

### Client Breaking Changes

* (runtime) [#19040](https://github.com/cosmos/cosmos-sdk/pull/19040) Simplify app config implementation and deprecate `/cosmos/app/v1alpha1/config` query.
* (runtime) [#19040](https://github.com/cosmos/cosmos-sdk/pull/19040) Simplify app config implementation and deprecate `/cosmos/app/v1alpha1/config` query.

### CLI Breaking Changes

* (perf)[#20490](https://github.com/cosmos/cosmos-sdk/pull/20490) Sims: Replace runsim command with Go stdlib testing. CLI: `Commit` default true, `Lean`, `SimulateEveryOperation`, `PrintAllInvariants`, `DBBackend` params removed
* (server) [#18303](https://github.com/cosmos/cosmos-sdk/pull/18303) `appd export` has moved with other genesis commands, use `appd genesis export` instead.
* (client/tx) [#20870](https://github.com/cosmos/cosmos-sdk/pull/20870) Removed `timeout-height` flag replace with `timeout-timestamp` flag for a time based timeout.

### Deprecated

Expand Down
2 changes: 1 addition & 1 deletion UPGRADING.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ transactions in your application:
anteDecorators := []sdk.AnteDecorator{
ante.NewSetUpContextDecorator(),
// ...
ante.NewUnorderedTxDecorator(unorderedtx.DefaultMaxUnOrderedTTL, app.UnorderedTxManager),
ante.NewUnorderedTxDecorator(unorderedtx.DefaultMaxTimeoutDuration, options.TxManager, options.Environment),
// ...
}

Expand Down
459 changes: 279 additions & 180 deletions api/cosmos/tx/v1beta1/tx.pulsar.go

Large diffs are not rendered by default.

14 changes: 12 additions & 2 deletions baseapp/abci_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1833,19 +1833,29 @@ func TestABCI_PrepareProposal_ReachedMaxBytes(t *testing.T) {
})
require.NoError(t, err)

expectedTxs := 8
var expectedTxBytes int64

for i := 0; i < 100; i++ {
tx2 := newTxCounter(t, suite.txConfig, int64(i), int64(i))
err := pool.Insert(sdk.Context{}, tx2)
require.NoError(t, err)

txBz, err := suite.txConfig.TxEncoder()(tx2)
require.NoError(t, err)
txDataSize := int(cmttypes.ComputeProtoSizeForTxs([]cmttypes.Tx{txBz}))
if i < expectedTxs {
expectedTxBytes += int64(txDataSize)
}
}

reqPrepareProposal := abci.PrepareProposalRequest{
MaxTxBytes: 1500,
MaxTxBytes: expectedTxBytes,
Height: 1,
}
resPrepareProposal, err := suite.baseApp.PrepareProposal(&reqPrepareProposal)
require.NoError(t, err)
require.Equal(t, 8, len(resPrepareProposal.Txs))
require.Equal(t, expectedTxs, len(resPrepareProposal.Txs))
}

func TestABCI_PrepareProposal_BadEncoding(t *testing.T) {
Expand Down
34 changes: 17 additions & 17 deletions baseapp/abci_utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -496,10 +496,10 @@ func (s *ABCIUtilsTestSuite) TestDefaultProposalHandler_NoOpMempoolTxSelection()
tx := builder.GetTx()
txBz, err := txConfig.TxEncoder()(tx)
s.Require().NoError(err)
s.Require().Len(txBz, 152)
s.Require().Len(txBz, 165)

txDataSize := int(cmttypes.ComputeProtoSizeForTxs([]cmttypes.Tx{txBz}))
s.Require().Equal(txDataSize, 155)
s.Require().Equal(txDataSize, 168)

testCases := map[string]struct {
ctx sdk.Context
Expand Down Expand Up @@ -532,15 +532,15 @@ func (s *ABCIUtilsTestSuite) TestDefaultProposalHandler_NoOpMempoolTxSelection()
Txs: [][]byte{txBz, txBz, txBz, txBz, txBz},
MaxTxBytes: 465,
},
expectedTxs: 3,
expectedTxs: 2,
},
"large max tx bytes len calculation": {
ctx: s.ctx,
req: &abci.PrepareProposalRequest{
Txs: [][]byte{txBz, txBz, txBz, txBz, txBz},
MaxTxBytes: 456,
MaxTxBytes: 504,
},
expectedTxs: 2,
expectedTxs: 3,
},
"max gas and tx bytes": {
ctx: s.ctx.WithConsensusParams(cmtproto.ConsensusParams{
Expand Down Expand Up @@ -619,15 +619,15 @@ func (s *ABCIUtilsTestSuite) TestDefaultProposalHandler_PriorityNonceMempoolTxSe
testTxs[i].size = int(cmttypes.ComputeProtoSizeForTxs([]cmttypes.Tx{bz}))
}

s.Require().Equal(180, testTxs[0].size)
s.Require().Equal(190, testTxs[1].size)
s.Require().Equal(181, testTxs[2].size)
s.Require().Equal(181, testTxs[3].size)
s.Require().Equal(263, testTxs[4].size)
s.Require().Equal(273, testTxs[5].size)
s.Require().Equal(264, testTxs[6].size)
s.Require().Equal(264, testTxs[7].size)
s.Require().Equal(264, testTxs[8].size)
s.Require().Equal(193, testTxs[0].size)
s.Require().Equal(203, testTxs[1].size)
s.Require().Equal(194, testTxs[2].size)
s.Require().Equal(194, testTxs[3].size)
s.Require().Equal(276, testTxs[4].size)
s.Require().Equal(286, testTxs[5].size)
s.Require().Equal(277, testTxs[6].size)
s.Require().Equal(277, testTxs[7].size)
s.Require().Equal(277, testTxs[8].size)

testCases := map[string]struct {
ctx sdk.Context
Expand All @@ -640,15 +640,15 @@ func (s *ABCIUtilsTestSuite) TestDefaultProposalHandler_PriorityNonceMempoolTxSe
ctx: s.ctx,
txInputs: []testTx{testTxs[0], testTxs[1], testTxs[2], testTxs[3]},
req: &abci.PrepareProposalRequest{
MaxTxBytes: 180 + 181,
MaxTxBytes: 193 + 194,
},
expectedTxs: []int{0, 3},
},
"skip multi-signers msg non-sequential sequence": {
ctx: s.ctx,
txInputs: []testTx{testTxs[4], testTxs[5], testTxs[6], testTxs[7], testTxs[8]},
req: &abci.PrepareProposalRequest{
MaxTxBytes: 263 + 264,
MaxTxBytes: 276 + 277,
},
expectedTxs: []int{4, 8},
},
Expand All @@ -657,7 +657,7 @@ func (s *ABCIUtilsTestSuite) TestDefaultProposalHandler_PriorityNonceMempoolTxSe
ctx: s.ctx,
txInputs: []testTx{testTxs[9], testTxs[10], testTxs[11]},
req: &abci.PrepareProposalRequest{
MaxTxBytes: 263 + 264,
MaxTxBytes: 276 + 277,
},
expectedTxs: []int{9},
},
Expand Down
6 changes: 3 additions & 3 deletions client/flags/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ const (
FlagPageKey = "page-key"
FlagOffset = "offset"
FlagCountTotal = "count-total"
FlagTimeoutHeight = "timeout-height"
FlagTimeoutTimestamp = "timeout-timestamp"
FlagUnordered = "unordered"
FlagKeyAlgorithm = "algo"
FlagKeyType = "key-type"
Expand Down Expand Up @@ -136,8 +136,8 @@ func AddTxFlagsToCmd(cmd *cobra.Command) {
f.Bool(FlagOffline, false, "Offline mode (does not allow any online functionality)")
f.BoolP(FlagSkipConfirmation, "y", false, "Skip tx broadcasting prompt confirmation")
f.String(FlagSignMode, "", "Choose sign mode (direct|amino-json|direct-aux|textual), this is an advanced feature")
f.Uint64(FlagTimeoutHeight, 0, "Set a block timeout height to prevent the tx from being committed past a certain height")
f.Bool(FlagUnordered, false, "Enable unordered transaction delivery; must be used in conjunction with --timeout-height")
f.Int64(FlagTimeoutTimestamp, 0, "Set a block timeout timestamp to prevent the tx from being committed past a certain time")
f.Bool(FlagUnordered, false, "Enable unordered transaction delivery; must be used in conjunction with --timeout-timestamp")
f.String(FlagFeePayer, "", "Fee payer pays fees for the transaction instead of deducting from the signer")
f.String(FlagFeeGranter, "", "Fee granter grants fees for the transaction")
f.String(FlagTip, "", "Tip is the amount that is going to be transferred to the fee payer on the target chain. This flag is only valid when used with --aux, and is ignored if the target chain didn't enable the TipDecorator")
Expand Down
17 changes: 14 additions & 3 deletions client/tx/aux_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ package tx

import (
"context"
"time"

"github.com/cosmos/gogoproto/proto"
"google.golang.org/protobuf/types/known/anypb"
"google.golang.org/protobuf/types/known/timestamppb"

txv1beta1 "cosmossdk.io/api/cosmos/tx/v1beta1"
txsigning "cosmossdk.io/x/tx/signing"
Expand Down Expand Up @@ -58,6 +60,14 @@ func (b *AuxTxBuilder) SetTimeoutHeight(height uint64) {
b.auxSignerData.SignDoc.BodyBytes = nil
}

// SetTimeoutTimestamp sets a timeout timestamp in the tx.
func (b *AuxTxBuilder) SetTimeoutTimestamp(timestamp time.Time) {
b.checkEmptyFields()

b.body.TimeoutTimestamp = timestamppb.New(timestamp)
b.auxSignerData.SignDoc.BodyBytes = nil
}

// SetMsgs sets an array of Msgs in the tx.
func (b *AuxTxBuilder) SetMsgs(msgs ...sdk.Msg) error {
anys := make([]*anypb.Any, len(msgs))
Expand Down Expand Up @@ -209,9 +219,10 @@ func (b *AuxTxBuilder) GetSignBytes() ([]byte, error) {
})

auxBody := &txv1beta1.TxBody{
Messages: body.Messages,
Memo: body.Memo,
TimeoutHeight: body.TimeoutHeight,
Messages: body.Messages,
Memo: body.Memo,
TimeoutHeight: body.TimeoutHeight,
TimeoutTimestamp: body.TimeoutTimestamp,
// AuxTxBuilder has no concern with extension options, so we set them to nil.
// This preserves pre-PR#16025 behavior where extension options were ignored, this code path:
// https://github.com/cosmos/cosmos-sdk/blob/ac3c209326a26b46f65a6cc6f5b5ebf6beb79b38/client/tx/aux_builder.go#L193
Expand Down
15 changes: 13 additions & 2 deletions client/tx/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"math/big"
"os"
"strings"
"time"

"github.com/cosmos/go-bip39"
"github.com/spf13/pflag"
Expand Down Expand Up @@ -33,6 +34,7 @@ type Factory struct {
sequence uint64
gas uint64
timeoutHeight uint64
timeoutTimestamp time.Time
gasAdjustment float64
chainID string
fromName string
Expand Down Expand Up @@ -86,7 +88,8 @@ func NewFactoryCLI(clientCtx client.Context, flagSet *pflag.FlagSet) (Factory, e

gasAdj := clientCtx.Viper.GetFloat64(flags.FlagGasAdjustment)
memo := clientCtx.Viper.GetString(flags.FlagNote)
timeoutHeight := clientCtx.Viper.GetUint64(flags.FlagTimeoutHeight)
timestampUnix := clientCtx.Viper.GetInt64(flags.FlagTimeoutTimestamp)
timeoutTimestamp := time.Unix(timestampUnix, 0)
unordered := clientCtx.Viper.GetBool(flags.FlagUnordered)

gasStr := clientCtx.Viper.GetString(flags.FlagGas)
Expand All @@ -104,7 +107,7 @@ func NewFactoryCLI(clientCtx client.Context, flagSet *pflag.FlagSet) (Factory, e
simulateAndExecute: gasSetting.Simulate,
accountNumber: accNum,
sequence: accSeq,
timeoutHeight: timeoutHeight,
timeoutTimestamp: timeoutTimestamp,
unordered: unordered,
gasAdjustment: gasAdj,
memo: memo,
Expand Down Expand Up @@ -135,6 +138,7 @@ func (f Factory) Fees() sdk.Coins { return f.fees }
func (f Factory) GasPrices() sdk.DecCoins { return f.gasPrices }
func (f Factory) AccountRetriever() client.AccountRetriever { return f.accountRetriever }
func (f Factory) TimeoutHeight() uint64 { return f.timeoutHeight }
func (f Factory) TimeoutTimestamp() time.Time { return f.timeoutTimestamp }
func (f Factory) Unordered() bool { return f.unordered }
func (f Factory) FromName() string { return f.fromName }

Expand Down Expand Up @@ -249,6 +253,12 @@ func (f Factory) WithTimeoutHeight(height uint64) Factory {
return f
}

// WithTimeoutTimestamp returns a copy of the Factory with an updated timeout timestamp.
func (f Factory) WithTimeoutTimestamp(timestamp time.Time) Factory {
f.timeoutTimestamp = timestamp
return f
}

// WithUnordered returns a copy of the Factory with an updated unordered field.
func (f Factory) WithUnordered(v bool) Factory {
f.unordered = v
Expand Down Expand Up @@ -361,6 +371,7 @@ func (f Factory) BuildUnsignedTx(msgs ...sdk.Msg) (client.TxBuilder, error) {
tx.SetFeeGranter(f.feeGranter)
tx.SetFeePayer(f.feePayer)
tx.SetTimeoutHeight(f.TimeoutHeight())
tx.SetTimeoutTimestamp(f.TimeoutTimestamp())
tx.SetUnordered(f.Unordered())

if etx, ok := tx.(client.ExtendedTxBuilder); ok {
Expand Down
3 changes: 3 additions & 0 deletions client/tx_config.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package client

import (
"time"

"cosmossdk.io/x/auth/signing"
txsigning "cosmossdk.io/x/tx/signing"

Expand Down Expand Up @@ -48,6 +50,7 @@ type (
SetFeePayer(feePayer sdk.AccAddress)
SetGasLimit(limit uint64)
SetTimeoutHeight(height uint64)
SetTimeoutTimestamp(timestamp time.Time)
SetUnordered(v bool)
SetFeeGranter(feeGranter sdk.AccAddress)
AddAuxSignerData(tx.AuxSignerData) error
Expand Down
4 changes: 2 additions & 2 deletions client/v2/autocli/testdata/help-echo-msg.golden
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Flags:
-o, --output string Output format (text|json) (default "json")
-s, --sequence uint The sequence number of the signing account (offline mode only)
--sign-mode string Choose sign mode (direct|amino-json|direct-aux|textual), this is an advanced feature
--timeout-height uint Set a block timeout height to prevent the tx from being committed past a certain height
--timeout-timestamp int Set a block timeout timestamp to prevent the tx from being committed past a certain time
--tip string Tip is the amount that is going to be transferred to the fee payer on the target chain. This flag is only valid when used with --aux, and is ignored if the target chain didn't enable the TipDecorator
--unordered Enable unordered transaction delivery; must be used in conjunction with --timeout-height
--unordered Enable unordered transaction delivery; must be used in conjunction with --timeout-timestamp
-y, --yes Skip tx broadcasting prompt confirmation
2 changes: 1 addition & 1 deletion client/v2/autocli/testdata/msg-output.golden
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"body":{"messages":[{"@type":"/cosmos.bank.v1beta1.MsgSend","from_address":"cosmos1y74p8wyy4enfhfn342njve6cjmj5c8dtl6emdk","to_address":"cosmos1y74p8wyy4enfhfn342njve6cjmj5c8dtl6emdk","amount":[{"denom":"foo","amount":"1"}]}]},"auth_info":{"fee":{"gas_limit":"200000"}}}
{"body":{"messages":[{"@type":"/cosmos.bank.v1beta1.MsgSend","from_address":"cosmos1y74p8wyy4enfhfn342njve6cjmj5c8dtl6emdk","to_address":"cosmos1y74p8wyy4enfhfn342njve6cjmj5c8dtl6emdk","amount":[{"denom":"foo","amount":"1"}]}],"timeout_timestamp":"1970-01-01T00:00:00Z"},"auth_info":{"fee":{"gas_limit":"200000"}}}
1 change: 1 addition & 0 deletions client/v2/offchain/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ func (b *builder) GetSigningTxData() (txsigning.TxData, error) {
Messages: msgs,
Memo: body.Memo,
TimeoutHeight: body.TimeoutHeight,
TimeoutTimestamp: body.TimeoutTimestamp,
ExtensionOptions: extOptions,
NonCriticalExtensionOptions: nonCriticalExtOptions,
}
Expand Down
Loading

0 comments on commit 5853356

Please sign in to comment.