Skip to content

Commit

Permalink
chore: tx status forward port (#3816)
Browse files Browse the repository at this point in the history
## Overview

Forward-porting some work that was only addressed on v2.x branch

---------

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
  • Loading branch information
ninabarbakadze and mergify[bot] committed Aug 28, 2024
1 parent 2f74d9b commit b9ff23d
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 44 deletions.
5 changes: 3 additions & 2 deletions app/test/big_blob_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,9 @@ func (s *BigBlobSuite) TestErrBlobsTooLarge() {
defer cancel()
res, err := txClient.SubmitPayForBlob(subCtx, []*share.Blob{tc.blob}, user.SetGasLimitAndGasPrice(1e9, appconsts.DefaultMinGasPrice))
require.Error(t, err)
require.NotNil(t, res)
require.Equal(t, tc.want, res.Code, err.Error())
require.Nil(t, res)
code := err.(*user.BroadcastTxError).Code
require.Equal(t, tc.want, code, err.Error())
})
}
}
16 changes: 11 additions & 5 deletions app/test/std_sdk_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -317,20 +317,26 @@ func (s *StandardSDKIntegrationTestSuite) TestStandardSDK() {
// sign and submit the transactions
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
serviceClient := sdktx.NewServiceClient(s.cctx.GRPCClient)
msgs, signer := tt.msgFunc()
txClient, err := user.SetupTxClient(s.cctx.GoContext(), s.cctx.Keyring, s.cctx.GRPCClient, s.ecfg, user.WithDefaultAccount(signer))
require.NoError(t, err)
res, err := txClient.SubmitTx(s.cctx.GoContext(), msgs, blobfactory.DefaultTxOpts()...)
if tt.expectedCode != abci.CodeTypeOK {
require.Error(t, err)
require.Nil(t, res)
txHash := err.(*user.ExecutionError).TxHash
code := err.(*user.ExecutionError).Code
getTxResp, err := serviceClient.GetTx(s.cctx.GoContext(), &sdktx.GetTxRequest{Hash: txHash})
require.NoError(t, err)
assert.Equal(t, tt.expectedCode, code, getTxResp.TxResponse.RawLog)
} else {
require.NoError(t, err)
require.NotNil(t, res)
getTxResp, err := serviceClient.GetTx(s.cctx.GoContext(), &sdktx.GetTxRequest{Hash: res.TxHash})
require.NoError(t, err)
assert.Equal(t, tt.expectedCode, res.Code, getTxResp.TxResponse.RawLog)
}
serviceClient := sdktx.NewServiceClient(s.cctx.GRPCClient)
getTxResp, err := serviceClient.GetTx(s.cctx.GoContext(), &sdktx.GetTxRequest{Hash: res.TxHash})
require.NoError(t, err)
require.NotNil(t, res)
assert.Equal(t, tt.expectedCode, res.Code, getTxResp.TxResponse.RawLog)
})
}
}
Expand Down
66 changes: 47 additions & 19 deletions pkg/user/tx_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
sdktx "github.com/cosmos/cosmos-sdk/types/tx"
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types/proposal"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/rpc/core"
"google.golang.org/grpc"

"github.com/celestiaorg/celestia-app/v3/app"
Expand All @@ -31,7 +32,6 @@ import (
"github.com/celestiaorg/celestia-app/v3/pkg/appconsts"
"github.com/celestiaorg/celestia-app/v3/x/blob/types"
"github.com/celestiaorg/celestia-app/v3/x/minfee"
"github.com/tendermint/tendermint/rpc/core"
)

const (
Expand All @@ -44,11 +44,36 @@ type Option func(client *TxClient)
// TxResponse is a response from the chain after
// a transaction has been submitted.
type TxResponse struct {
// Height is the block height at which the transaction was included on-chain.
Height int64
TxHash string
Code uint32
}

// BroadcastTxError is an error that occurs when broadcasting a transaction.
type BroadcastTxError struct {
TxHash string
Code uint32
// ErrorLog is the error output of the app's logger
ErrorLog string
}

func (e *BroadcastTxError) Error() string {
return fmt.Sprintf("broadcast tx error: %s", e.ErrorLog)
}

// ExecutionError is an error that occurs when a transaction gets executed.
type ExecutionError struct {
TxHash string
Code uint32
// ErrorLog is the error output of the app's logger
ErrorLog string
}

func (e *ExecutionError) Error() string {
return fmt.Sprintf("tx execution failed with code %d: %s", e.Code, e.ErrorLog)
}

// WithGasMultiplier is a functional option allows to configure the gas multiplier.
func WithGasMultiplier(multiplier float64) Option {
return func(c *TxClient) {
Expand Down Expand Up @@ -213,7 +238,7 @@ func SetupTxClient(
func (client *TxClient) SubmitPayForBlob(ctx context.Context, blobs []*share.Blob, opts ...TxOption) (*TxResponse, error) {
resp, err := client.BroadcastPayForBlob(ctx, blobs, opts...)
if err != nil {
return parseTxResponse(resp, fmt.Errorf("failed to broadcast pay for blob: %v", err))
return nil, err
}

return client.ConfirmTx(ctx, resp.TxHash)
Expand All @@ -224,7 +249,7 @@ func (client *TxClient) SubmitPayForBlob(ctx context.Context, blobs []*share.Blo
func (client *TxClient) SubmitPayForBlobWithAccount(ctx context.Context, account string, blobs []*share.Blob, opts ...TxOption) (*TxResponse, error) {
resp, err := client.BroadcastPayForBlobWithAccount(ctx, account, blobs, opts...)
if err != nil {
return parseTxResponse(resp, fmt.Errorf("failed to broadcast pay for blob with account: %v", err))
return nil, err
}

return client.ConfirmTx(ctx, resp.TxHash)
Expand Down Expand Up @@ -268,7 +293,7 @@ func (client *TxClient) BroadcastPayForBlobWithAccount(ctx context.Context, acco
func (client *TxClient) SubmitTx(ctx context.Context, msgs []sdktypes.Msg, opts ...TxOption) (*TxResponse, error) {
resp, err := client.BroadcastTx(ctx, msgs, opts...)
if err != nil {
return parseTxResponse(resp, fmt.Errorf("failed to broadcast tx: %v", err))
return nil, err
}

return client.ConfirmTx(ctx, resp.TxHash)
Expand Down Expand Up @@ -354,7 +379,12 @@ func (client *TxClient) broadcastTx(ctx context.Context, txBytes []byte, signer
}
return client.retryBroadcastingTx(ctx, txBytes)
}
return resp.TxResponse, fmt.Errorf("tx failed with code %d: %s", resp.TxResponse.Code, resp.TxResponse.RawLog)
broadcastTxErr := &BroadcastTxError{
TxHash: resp.TxResponse.TxHash,
Code: resp.TxResponse.Code,
ErrorLog: resp.TxResponse.RawLog,
}
return resp.TxResponse, broadcastTxErr
}

// after the transaction has been submitted, we can increment the
Expand Down Expand Up @@ -435,16 +465,16 @@ func (client *TxClient) ConfirmTx(ctx context.Context, txHash string) (*TxRespon
for {
resp, err := txClient.TxStatus(ctx, &tx.TxStatusRequest{TxId: txHash})
if err != nil {
return &TxResponse{}, err
return nil, err
}

if err == nil && resp != nil {
if resp != nil {
switch resp.Status {
case core.TxStatusPending:
// Continue polling if the transaction is still pending
select {
case <-ctx.Done():
return &TxResponse{}, ctx.Err()
return nil, ctx.Err()
case <-pollTicker.C:
continue
}
Expand All @@ -454,14 +484,19 @@ func (client *TxClient) ConfirmTx(ctx context.Context, txHash string) (*TxRespon
TxHash: txHash,
Code: resp.ExecutionCode,
}
if resp.ExecutionCode != 0 {
return txResponse, fmt.Errorf("tx was committed but failed with code %d: %s", resp.ExecutionCode, resp.Error)
if resp.ExecutionCode != abci.CodeTypeOK {
executionErr := &ExecutionError{
TxHash: txHash,
Code: resp.ExecutionCode,
ErrorLog: resp.Error,
}
return nil, executionErr
}
return txResponse, nil
case core.TxStatusEvicted:
return &TxResponse{TxHash: txHash}, fmt.Errorf("tx: %s was evicted from the mempool", txHash)
return nil, fmt.Errorf("tx was evicted from the mempool")
default:
return &TxResponse{}, fmt.Errorf("unknown tx: %s", txHash)
return nil, fmt.Errorf("unknown tx: %s", txHash)
}
}
}
Expand Down Expand Up @@ -569,13 +604,6 @@ func (client *TxClient) getAccountNameFromMsgs(msgs []sdktypes.Msg) (string, err
return record.Name, nil
}

func parseTxResponse(resp *sdktypes.TxResponse, err error) (*TxResponse, error) {
if resp != nil {
return &TxResponse{Code: resp.Code, TxHash: resp.TxHash}, err
}
return &TxResponse{}, err
}

// Signer exposes the tx clients underlying signer
func (client *TxClient) Signer() *Signer {
return client.signer
Expand Down
7 changes: 4 additions & 3 deletions pkg/user/tx_client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

sdk "github.com/cosmos/cosmos-sdk/types"
sdktx "github.com/cosmos/cosmos-sdk/types/tx"
"github.com/cosmos/cosmos-sdk/x/authz"
bank "github.com/cosmos/cosmos-sdk/x/bank/types"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
Expand All @@ -19,7 +20,6 @@ import (
"github.com/celestiaorg/celestia-app/v3/pkg/user"
"github.com/celestiaorg/celestia-app/v3/test/util/blobfactory"
"github.com/celestiaorg/celestia-app/v3/test/util/testnode"
"github.com/cosmos/cosmos-sdk/x/authz"
)

func TestTxClientTestSuite(t *testing.T) {
Expand Down Expand Up @@ -209,9 +209,10 @@ func (suite *TxClientTestSuite) TestConfirmTx() {
resp, err := suite.txClient.BroadcastTx(suite.ctx.GoContext(), []sdk.Msg{msg}, fee, gas)
require.NoError(t, err)
require.NotNil(t, resp)
confirmTxResp, err := suite.txClient.ConfirmTx(suite.ctx.GoContext(), resp.TxHash)
_, err = suite.txClient.ConfirmTx(suite.ctx.GoContext(), resp.TxHash)
require.Error(t, err)
require.NotEqual(t, abci.CodeTypeOK, confirmTxResp.Code)
code := err.(*user.ExecutionError).Code
require.NotEqual(t, abci.CodeTypeOK, code)
})
}

Expand Down
16 changes: 11 additions & 5 deletions x/blobstream/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,20 +81,26 @@ func (s *BlobstreamIntegrationSuite) TestBlobstream() {
// sign and submit the transactions
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
serviceClient := sdktx.NewServiceClient(s.cctx.GRPCClient)
msgs, _ := tt.msgFunc()
txClient, err := user.SetupTxClient(s.cctx.GoContext(), s.cctx.Keyring, s.cctx.GRPCClient, s.ecfg)
require.NoError(t, err)
res, err := txClient.SubmitTx(s.cctx.GoContext(), msgs, blobfactory.DefaultTxOpts()...)
if tt.expectedTxCode == abci.CodeTypeOK {
require.NoError(t, err)
require.NotNil(t, res)
getTxResp, err := serviceClient.GetTx(s.cctx.GoContext(), &sdktx.GetTxRequest{Hash: res.TxHash})
require.NoError(t, err)
require.Equal(t, tt.expectedTxCode, res.Code, getTxResp.TxResponse.RawLog)
} else {
require.Error(t, err)
require.Nil(t, res)
txHash := err.(*user.ExecutionError).TxHash
code := err.(*user.ExecutionError).Code
getTxResp, err := serviceClient.GetTx(s.cctx.GoContext(), &sdktx.GetTxRequest{Hash: txHash})
require.NoError(t, err)
require.Equal(t, tt.expectedTxCode, code, getTxResp.TxResponse.RawLog)
}
serviceClient := sdktx.NewServiceClient(s.cctx.GRPCClient)
getTxResp, err := serviceClient.GetTx(s.cctx.GoContext(), &sdktx.GetTxRequest{Hash: res.TxHash})
require.NoError(t, err)
require.NotNil(t, res)
require.Equal(t, tt.expectedTxCode, res.Code, getTxResp.TxResponse.RawLog)
})
}
}
23 changes: 13 additions & 10 deletions x/signal/legacy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

"github.com/celestiaorg/celestia-app/v3/app"
"github.com/celestiaorg/celestia-app/v3/app/encoding"
"github.com/celestiaorg/celestia-app/v3/pkg/user"
testutil "github.com/celestiaorg/celestia-app/v3/test/util"
"github.com/celestiaorg/celestia-app/v3/test/util/blobfactory"
"github.com/celestiaorg/celestia-app/v3/test/util/genesis"
Expand Down Expand Up @@ -120,14 +121,14 @@ func (s *LegacyUpgradeTestSuite) TestLegacyGovUpgradeFailure() {
require.NoError(t, err)

// submit the transaction and wait a block for it to be included
signer, err := testnode.NewTxClientFromContext(s.cctx)
txClient, err := testnode.NewTxClientFromContext(s.cctx)
require.NoError(t, err)
subCtx, cancel := context.WithTimeout(s.cctx.GoContext(), time.Minute)
defer cancel()
res, err := signer.SubmitTx(subCtx, []sdk.Msg{msg}, blobfactory.DefaultTxOpts()...)
require.Error(t, err)
_, err = txClient.SubmitTx(subCtx, []sdk.Msg{msg}, blobfactory.DefaultTxOpts()...)
code := err.(*user.BroadcastTxError).Code
// As the type is not registered, the message will fail with unable to resolve type URL
require.EqualValues(t, 2, res.Code)
require.EqualValues(t, 2, code, err.Error())
}

// TestNewGovUpgradeFailure verifies that a transaction with a
Expand All @@ -149,14 +150,15 @@ func (s *LegacyUpgradeTestSuite) TestNewGovUpgradeFailure() {
require.NoError(t, err)

// submit the transaction and wait a block for it to be included
signer, err := testnode.NewTxClientFromContext(s.cctx)
txClient, err := testnode.NewTxClientFromContext(s.cctx)
require.NoError(t, err)
subCtx, cancel := context.WithTimeout(s.cctx.GoContext(), time.Minute)
defer cancel()
res, err := signer.SubmitTx(subCtx, []sdk.Msg{msg}, blobfactory.DefaultTxOpts()...)
require.Error(t, err)
_, err = txClient.SubmitTx(subCtx, []sdk.Msg{msg}, blobfactory.DefaultTxOpts()...)
// As the type is not registered, the message will fail with unable to resolve type URL
require.EqualValues(t, 2, res.Code)
require.Error(t, err)
code := err.(*user.BroadcastTxError).Code
require.EqualValues(t, 2, code, err.Error())
}

func (s *LegacyUpgradeTestSuite) TestIBCUpgradeFailure() {
Expand All @@ -182,9 +184,10 @@ func (s *LegacyUpgradeTestSuite) TestIBCUpgradeFailure() {
require.NoError(t, err)
subCtx, cancel := context.WithTimeout(s.cctx.GoContext(), time.Minute)
defer cancel()
res, err := txClient.SubmitTx(subCtx, []sdk.Msg{msg}, blobfactory.DefaultTxOpts()...)
_, err = txClient.SubmitTx(subCtx, []sdk.Msg{msg}, blobfactory.DefaultTxOpts()...)
require.Error(t, err)
require.EqualValues(t, 9, res.Code) // we're only submitting the tx, so we expect everything to work
code := err.(*user.ExecutionError).Code
require.EqualValues(t, 9, code) // we're only submitting the tx, so we expect everything to work
assert.Contains(t, err.Error(), "ibc upgrade proposal not supported")
}

Expand Down

0 comments on commit b9ff23d

Please sign in to comment.